Re: How to model a rectangle?

2015-03-05 Thread Felix E. Klee
Looks interesting, thanks!

On Thu, Mar 5, 2015 at 4:43 PM, Leon Grapenthin
grapenthinl...@gmail.com wrote:
 (defn rect2 [x y width height]
   (let [lr  [(+ width x) (+ width y)]]
 (reify Rect
   (upper-left [_] [x y])
   (lower-right [_] lr)
   (area [_] (* width height)

Just a quick remark: In JavaScript I purposefully did not use `width`
and `height` for calculating area. That way the garbage collector can
release them, making objects smaller.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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.


How to model a rectangle?

2015-03-05 Thread Felix E. Klee
Disclaimer: I’ve never done *any* Clojure programming, but I’m curious.

Here’s how I may model an on-screen rectangle in JavaScript, a classless
object oriented language:

let createRectangle = function (x, y, width, height) {
return {
get upperLeft() {
return [x, y];
},
get lowerRight() {
return [x + width, y + height];
},
get area() {
return width * height;
}
};
};

let r = createRectangle(0, 0, 50, 20);
let s = createRectangle(10, 20, 40, 5);
console.log(r.upperLeft, r.lowerRight, r.area);
console.log(s.upperLeft, s.lowerRight, s.area);

Now I run the profiler. I discover that in the inner loop of my program
there are lots of calls needing the upper left and the lower right
coordinates. So I change the inner workings of the object to store these
instead:

let createRectangle = function (x, y, width, height) {
let upperLeft = [x, y], lowerRight = [x + width, y + height];

return {
get upperLeft() {
return upperLeft;
},
get lowerRight() {
return lowerRight;
},
get area() {
return (lowerRight[0] - upperLeft[0]) *
(lowerRight[1] - upperLeft[1]);
}
};
};

Boom: Now the program is twice as fast, and - what gives me great
comfort - I know that this change breaks nothing. I only had to edit the
code in *one* module. I didn’t need to think too much about efficiency
of data structures in the beginning. I could just start going, then
optimize in the end.

*Can I program in a similar way using Clojure?*

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: edn

2012-09-08 Thread Steven E. Harris
Michael Fogus mefo...@gmail.com writes:

 Data formats do not exist in a vacuum.  They are parsed by languages.
 Some may have a fine-grained distinction between lists, arrays/vectors
 and sets and some may not.

The concern I have is for someone wanting to define a format atop EDN --
or, to put it differently, to define a schema for it. If we want to
define a structure to be represented in EDN such as a list of a person's
favorite colors, on what basis would the schema author choose between
list and vector notation? Is there a higher-level abstract type that he
specify and require that a conforming processor accept either a list or
vector literal?

Even if he could mandate that, say, the favorite color list is of type
sequence -- listed in descending order of preference -- then an author
creating the EDN to represent such a person again has to make a choice
between a list and a vector, again without a clear basis for his
decision.

As an appeal to prior art, Rivest's S-Expressions Internet-Draft¹ used
only a single list structure, though it does define three different
encodings for that structure.


Footnotes: 
¹ http://people.csail.mit.edu/rivest/Sexp.txt

-- 
Steven E. Harris

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


Re: edn

2012-09-08 Thread Steven E. Harris
Ben Smith-Mannschott bsmith.o...@gmail.com writes:

 I follow forbidding -4bar since that means potentially unbounded
 look-ahead to distinguish numbers from non-numbers.

 Presumably forbidding .4bar is for the same reason, though .01
 doesn't appear to be a valid numeric literal. (Numeric literals all
 start with a digit.)

Common Lisp provides useful precedent with its notion of potential
numbers¹. If we stretch the analogy of namespace syntax to Common Lisp
package syntax, clause 3 in HyperSpec section 2.3.1.1² -- Potential
Numbers as Tokens -- is relevant to your cases above.

,[ §2.3.1.1 ]
| 3. The token begins with a digit, sign, decimal point, or extension
|character, but not a package marker. The syntax involving a leading
|package marker followed by a potential number is not
|well-defined. The consequences of the use of notation such as :1,
|:1/2, and :2^3 in a position where an expression appropriate for read
|is expected are unspecified.
`

Well, I suppose that's precluding using the package marker without an
actual package name ahead of it, like using '/' without a namespace name
before it.

In any case, Common Lisp parses both -4bar and .4bar as symbols:

,
| * (loop for s in '(-4bar .4bar) collect (type-of (read-from-string s)))
| (SYMBOL SYMBOL)
`


Footnotes: 
¹ 
http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_p.htm#potential_number
² http://www.lispworks.com/documentation/HyperSpec/Body/02_caa.htm

-- 
Steven E. Harris

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


Re: edn

2012-09-08 Thread Steven E. Harris
Armando Blancas abm221...@gmail.com writes:

 I'd say on the basis of convenience, since we get to serialize and
 deserialize for free (o with customizations), and for most cases the
 author on both ends is likely to be the same person or team.

I find that to be a specious defense. If we expect the same author to be
on both ends of the wire or reading the files he wrote himself, why take
interest in such a specified format anyway?

 For other languages, producers don't work any harder either way, and
 consumers are free to interpret both the schema and data as they
 need.

It sounds like you've ignored the thrust of my concern rather than
settling it.

 sexp's only have a list notation because that's all lisp had, and even
 then, some people got it all for free.

That tail did not wag that dog.

-- 
Steven E. Harris

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


Re: Tail-recursive lazy sequence construction by appending to the end of accumulator problem.

2012-07-14 Thread Steven E. Harris
Alexander Semenov bohtva...@gmail.com writes:

 The second lazy approach still needs to traverse all the sequence
 recursively, why doesn't it cause stack overflow?

You might find my answer to the StackOverflow question Thinking in Lazy
Sequences useful here:

  http://stackoverflow.com/a/2214049/31818

Note that I wrote it about a year and a half ago. I hope the references
to the Java classes are still correct.

-- 
Steven E. Harris

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


Re: Leiningen2 + lein-midje + lazytest question

2012-06-12 Thread Daniel E. Renfer

On 06/12/2012 12:05 PM, Phil Hagelberg wrote:

On Mon, Jun 11, 2012 at 1:46 PM, Phil Hagelbergp...@hagelb.org  wrote:

On Mon, Jun 11, 2012 at 12:52 PM, Cédric Pineaucedric.pin...@gmail.com  wrote:

My question is with the lazy-test dependency. Do I really have to put it as
a project dependency ?
It doesn't seem to be on the lein-midje path when puting it in the
dev-dependencies..

If it's required for lein-midje then lein-midje should add it to your
dependencies without you needing to do anything.

I should clarify that I know nothing about lein-midje in particular;
I'm just commenting on what the proper behaviour of plugins should be.

-Phil


The issue here is that Midje and lein-midje don't need Lazytest for 
normal operation, only for the --lazytest support. What would be the 
proper way to specify that dependency without requiring that everyone 
that uses Midje also carry around Lazytest?


I know the answer would probably be needing a lein-midje-lazytest 
artifact that adds that support, but that seems overkill.


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


A question of technique: clojure-hadoop's patching of methods

2012-03-06 Thread Steven E. Harris
Recently I was studying Stuart Sierra's clojure-hadoop project¹, and
there saw a technique that I'd like to discuss. There's a Java class
generated whose method definitions get patched based on a provided
configuration, and I'd like to understand the scope of this patching and
why the technique's effects are acceptable for this project.

The namespace clojure-hadoop.job² uses the macro
clojure-hadoop.gen/gen-job-classes³ to, well, generate a few Java
classes. Later, in the job/configure-functions functionº, we see use of
the alter-var-root function to change the functions associated with the
Java methods Mapper#map() (here, mapper-map) and Reducer#reduce() (here,
reducer-reduce).

Now to my questions. This mutation of the
class-method-to-Clojure-function binding appears to be global.  Will
it impact /all/ instances of the generated classes within this Clojure
process?

If this impact is global, is it the case that this software never needs
to accommodate instances of these generated classes with different
configurations? In other words, the job-related classes wind up
getting mutated to conform to one particular configuration. That means
that a given run of the program can't handle more than one configuration
at a time. Is that acceptable here because Hadoop is only going to load
these classes for use with a single configuration?

The patching looks like an optimization to avoid associating functions
with each Mapper or Reducer /instance/, so that it avoids that kind of
which-function-should-I-call-now lookup on each invocation. Is that a
correct interpretation of the design rationale?


Footnotes: 
¹ https://github.com/stuartsierra/clojure-hadoop
² 
https://github.com/stuartsierra/clojure-hadoop/blob/master/src/main/clojure/clojure_hadoop/job.clj
³ 
https://github.com/stuartsierra/clojure-hadoop/blob/master/src/main/clojure/clojure_hadoop/gen.clj#L5
º 
https://github.com/stuartsierra/clojure-hadoop/blob/master/src/main/clojure/clojure_hadoop/job.clj#L31

-- 
Steven E. Harris

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


Re: A question of technique: clojure-hadoop's patching of methods

2012-03-06 Thread Steven E. Harris
Stuart Sierra the.stuart.sie...@gmail.com writes:

 I haven't looked at that code in a long time, but the answer is yes. Each
 Hadoop Job runs in its own JVM process.

Thank you. That makes sense, then.

 Just to nail it home, though, do you agree that this patching technique
 is generally /not/ tenable in programs that need to use several
 instances of a such a class, each with different configuration? I think
 we'd either need another layer of indirection in the method dispatch,
 or instead use a class-generating macro that demands that configuration
 at macroexpansion time, creating a distinct class for each.

-- 
Steven E. Harris

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


Re: defmulti and defmethods in separate namespaces without circular references?

2012-03-02 Thread Daniel E. Renfer
I use a lot of multimethods with my framework, Ciste[0] and it can work,
the only thing is you have to be very careful about what you put where,
and it helps to have a lot of namespaces.

What I do is try to keep all of my defmulti's in one namespace and have
only defmethod's in another namespace. Originally, I had one master
namespace that required all of the defmethod namespaces (my routes
namespace) and then all my action namespaces only require the defmulti
namespaces.

I've since then moved on to use the 'definitializer' functionality of
Ciste to require those defmethod namespaces after all of the other
namespaces have been required.

I'm not saying it's the best coding style, but it works for me and my
applications. Be prepared to move functions around a lot to always stay
one step ahead of the dreaded cyclic dependency horror.

0: https://github.com/duck1123/ciste

On 03/02/2012 10:55 AM, Cymen Vig wrote:
 On Friday, March 2, 2012 7:03:10 AM UTC-6, tim.visher wrote:

 I will not in any way claim to know how or why this works. I'm just
 starting to use multimethods myself, but I'll give you my set up that
 appears to be working at the moment.

 I have a namespace:

 (ns store.store)

 (defmulti serialize method)

 (defmulti slurp method)

 in store.clj

 I have 1 implementation:

 (ns store.file-system
   [:use [store.store]]
   …)

 (def base )

 (defmethod serialize :file-system [_ file-name contents]
   (fs-utils/write-to contents (str base / file-name)))

 (defmethod slurp :file-system [_ file-name]
   (clojure.core/slurp (str base / file-name)))

 I then use this from another namespace, requiring store.store and
 store.store.file-system:

 (ns library
   [:require [wallpaper-manager-core.store.file-system :as
 store-file-system]]
   [:require [wallpaper-manager-core.store.store :as store]])

 (binding [store-file-system/base (fs/home)]
   (def library (ref (read-library) :validator library-validator)))

 (defn serialize-library [library]
   (store/serialize :file-system library.clj library))

 And this all seems to work fine for me. Maybe someone else can explain
 why it does for me and doesn't for you. Maybe it has something to do
 with `use` vs. `require`?

 This does indeed work for me. What I was trying to do was avoid was
 having to do this part:

...
   [:require [wallpaper-manager-core.store.store :as store]])

 As each time I add a defmethod implementation of my defmulti I'd have
 to add another require. But maybe that isn't such a bad thing so I'll
 go with this approach. I prefer it over having a super parent (*)
 namespace unless i needed that super parent in multiple places.

 * by super parent I mean a namespace that is only used to include
 the namespaces that contain the defmulti and defmethods

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

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

Re: Bret Victor - Inventing on Principle

2012-02-24 Thread Daniel E. Renfer
On 02/24/2012 02:42 PM, Cedric Greevey wrote:
 On Fri, Feb 24, 2012 at 2:25 PM, Jay Fields j...@jayfields.com wrote:
 On Fri, Feb 24, 2012 at 2:12 PM, Cedric Greevey cgree...@gmail.com wrote:
 On Fri, Feb 24, 2012 at 2:06 PM, gaz jones gareth.e.jo...@gmail.com wrote:
 Are you Ken Wesson with a new account?
 Who?

 Wait. Surely you don't think that it's not possible for more than one
 person to prefer text to video as a way of disseminating verbal
 information over the internet, given all of text's advantages in such
 areas as bandwidth, cost, and tool support?
 Surely it's possible that you've never heard of Ken Wesson, he
 disappeared right before you joined, you respond to emails in the same
 manner, you share the same opinions. Seems legit, Ken.
 OK. I googled the group archives. Seems there was a Ken Wesson active
 on the list for a while, but he disappeared a couple of months before
 I joined. I'm not sure why people think I might be him.


Ken Wesson was noted for having strong opinions as was a noted hater of
videos where text will do.

https://groups.google.com/d/msg/clojure/0kCwGrFU5zs/NGclkY46fvEJ

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


Re: Controlling the test environment

2012-01-20 Thread Daniel E. Renfer
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 01/15/2012 06:18 PM, Matt Stump wrote:
 
 
 Is there a way to set different values for global vars when running
 tests as opposed to the development or production environment?  I
 need to control which database my tests for a noir project connect
 to. Ideally I would like to do something like the following: for
 production and development, if an environment variable is set
 connect to the database server at the specified URL, if not then
 fall back to localhost.  For test start up an embedded server, and
 connect. After the test is done, rollback the global var to the
 previous value and resume connecting to the server on localhost or
 at the location specified by the environment variable.
 
 I could create some fixture with-test-database that modifies a
 global var, but that seems a little hackish.
 
 How are other people solving this problem?  Is there something
 similar pre-baked into noir, clojure.test or midje?
 

I wrote support for configuration with different environments into
Ciste.[1]

You create a config.clj file at the root of your application that
contains a map with each of the keys being a keyword naming the
environment and the value is a map for all the config options.

You can then use set-environment! or with-environment to set the
current environment.

You can then wrap some code in definitializer. That code will be run
whenever the environment changes. I set the environment when my
application runs and then wrap all my tests in (with-environment :test )


The config namespace should be isolated enough that you could use it
without involving any of the other features.



1: https://github.com/duck1123/ciste/
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk8ZoO0ACgkQWorbjR01Cx59cACffeQeffgR0zgtqt5FXGaQy9gx
zz8An2pMclSd+qA8dxc8XMPB+gMbhNjR
=XbSs
-END PGP SIGNATURE-

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


Re: repl output for list seems inconsistent and a holdover from yesteryear

2011-10-27 Thread e
On Oct 26, 2011 7:15 PM, Stuart Halloway stuart.hallo...@gmail.com
wrote:

 checking out the Try Clojure:

 if you type the following, you get output that matches what you typed
 in every case except for lists.

 Vectors: -- [1 2 3 4]
 [1 2 3 4]

 Maps: -- {:foo bar 3 4}
 {:foo bar 3 4}

 Lists: -- '(1 2 3 4)
 (1 2 3 4)  - *INCONSISTENT* why not render this as '(1 2 3 4) ...
 this would make much more sense to newbies.

 Sets: -- #{1 2 3 4}
 #{1 2 3 4}


 This is an interesting question. Consistency is important, but consistency
with what? Your mental model for what happens at the REPL needs to keep the
R, E, and P steps clearly separate.

 Working backward:  the P (Print) prints things in a way that they can be
read back, where possible:

 (read-string [1 2 3 4])
 = [1 2 3 4]

 (read-string (1 2 3 4))
 = (1 2 3 4)

 (read-string #{1 2 3 4})
 = #{1 2 3 4}

 (read-string {1 2 3 4})
 =  {1 2, 3 4}

 If the P part of the REPL put a tick in front of lists, they would not
read back correctly:

 (read-string '(1 2 3 4))
 = (quote (1 2 3 4)) INCONSISTENT


I see the problem that token  '  is already taken to be short hand for
quote so to be truly consistent, I might be compelled to argue that
(read-string '(1 2 3 4)) should, seeing some hypothetical list start
multi-char token  '(   just like set-start is  #{ , be: = '(1 2 3
4).

You'd need two single quotes: ''(1 2 3 4) to get quote '(1 2 3 4) ...
Wheras (1 2 3 4) means call 1 with ...

I'll have to reread the explanation about the repl phases, but maybe I'm
wondering if things don't have to be quoted if lists had the syntax I
describe, and requests for function invocation had a simple paren.  Then you
are not saying, treat this as data, do not eval.  You are just saying,
see my single quote paren token? That's for lists.

Maybe it would be clearer if I proposed some other, lesser-used chars, like
%(1 2 3 4) or even 1 2 3 4.  That is, I'm not so much saying, this
needs to be treated as data and not eval'd as I am simply saying, this is
the 'list' data structure as opposed to some other.

Now, if you ever need to read in a program and treat it like data, well,
what structure would you like to put it in? A list? A vector? A string? This
is, indeed, where I am fuzzy on lisps, but it seems like you parse it as
desired and put it where/how you like it.  Why is there an assumption that
code as data means code as lists? Or is there?

 Now to the R (Reader) part. If, as you suggest, the tick were part of the
reader syntax for lists, you could fix the inconsistency above:

 ;; hypothetical Clojure with '(...) list literals
 (read-string '  '(1 2 3 4))
 = (1 2 3 4)

 Finally, consider the poor E (Evaluator) in this scenario.  The evaluator
must (1) evaluate lists except (2) *not* evaluate lists that are protected
by quote. But now that the tick is part of the syntax you have two
challenges:

 (1) Since the tick no longer prevents evaluation, you have to spell out
the quote (and still use the tick!)

 ;; hypothetical literal list
 (quote '(1 2 3))

 (2) Since the tick is required as part of list syntax, your programs have
to be written with ticks everywhere like this:

 '(defn hello-world
   []
   '(println hello)

 You have to understand R, E and P as separate steps to understand the
REPL.

 As a side note, it is worth mentioning that the REPL is composed of three
simple parts, and that interactive shells that do not have this factoring
are much less useful. Imagine if your language didn't separate reading and
evaluating. You would need JSON or something to serialize data...

 Stu


 Stuart Halloway
 Clojure/core
 http://clojure.com

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

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

Re: repl output for list seems inconsistent and a holdover from yesteryear

2011-10-27 Thread e
You can also use the list function if you don't care about syntactic sugar,
and it seems. Like it should look like this:

= (list 1 2 3 4)
'(1 2 3 4)
or
1 2 3 4  -- although i'd use that for vectors and use [] for lists.

Wouldn't that be cool?
I imagine (set 1 2 3 4) prints as #{1 2 3 4}
On Oct 27, 2011 5:46 PM, Nicolas bousque...@gmail.com wrote:

 Hi!

 Well [1 2 3] is just a syntaxic sugar for (vector 1 2 3):
 =(vector 1 2 3)
 [1 2 3]

 When you enter a vector in the repl, it is evaluted to itself. Here an
 example that show it:
 =[1 2 (+ 1 2)]
 [1 2 3]

 And you can use the vector function for the same result:
 =(vector 1 2 (+ 1 2))
 [1 2 3]

 The quote prevent evaluation but this is not specific to lists:
 ='[1 2 (+ 1 2)]
 [1 2 (+ 1 2)]

 The way to make function calls in lisp (and in clojure) is to consider
 the first element of the list to be the function, and the next one to
 be the argument of the function. This what happen when you perform say
 an addition
 (+ 1 2) is a call to the add function with 2 parameters.

 But this mean that you can't define a list (data structure) just by
 writing it, because it will be evaluated. To prevent this, maybe the
 best solution is to use the list function, that return a list with its
 arguments.
 =(list 1 2 3)
 (1 2 3)

 You see the consistency here. As vectors are contructed with vector
 function. Notice calling the list function is very different that
 using a quote:
 =(list 1 2 (+ 1 2))
 (1 2 3)
 ='(1 2 (+ 1 2))
 (1 2 (+ 1 2))

 This mean that you might not want to use quote everywhere just to say
 'here is a list data structure'.

 The preference for vectors as data structure when possible is to make
 code more lisible. Using a list is just adding more parens, in a
 language with lot of parens. Doesn't help the reading.

 Using syntaxic sugar for vector, on the contrary help the reading.

 On 27 oct, 01:08, e evier...@gmail.com wrote:
  not necessarily.
 
  [1 2 3] is a vector that is not evaluated.  Since there is no overload
 with
  things that are, there's no need for a special mark.
 
  '(1 2 3) is currently a way of say, don't evaluate this list, but it
 could
  have been:
 
  '(1 2 3) is a list that is not evaluated.  No loss of generality.  it's a
  special type of list.  One that's not evaluated.  as opposed to a special
  indicator to the repl.
 
  On Wed, Oct 26, 2011 at 6:09 PM, Mark Rathwell mark.rathw...@gmail.com
 wrote:
 
 
 
 
 
 
 
   The point to think about here is that functions are also lists, the
   same as your list of integers.  The difference is that one is
   evaluated, the other is not.  That is what the quote is saying: don't
   evaluate me.  The quote is not actually a part of the list. It's just
   the way you tell the reader not to evaluate the list that follows.
 
   So the question is should all unevaluated forms be preceded with a
   quote in the repl output?  To me that would be more confusing.
 
   On Wed, Oct 26, 2011 at 5:34 PM, e evier...@gmail.com wrote:
long long time since I last looked a clojure, but I've never lost
interest and I'm trying to find the time again.
 
for the short version see *INCONSISTENT*, in the example at the
 end.
 
I know what the answer will be here.  Something like you will get
used to it. or it's not important. or no one hardly uses lists
anymore, anyway, since vectors are not purely contiguous.  But, if
you can make things better and it's easy, then why not?
 
So here's the deal:
 
I still think the following is only inconsistent because that's how
 it
was in older lisps.  Specifically, lists had to be quoted so the
 first
argument wouldn't be called as a function.  I asked long ago (here
 and
in person) why, then regular functions couldn't require the quote so
the paren could be reserved for the list data structure, and Rich
answered that it'd simply be a pain to have to quote every function
call.  Well, my mind moves slowly.  I'm just now realizing to ask,
Ok, then how about making the list really be defined using the
 single
quote as part of it just like sets include the sharp to distinguish
them from maps?.  That's a much simpler explanation than saying,
 you
have to escape them, etc, etc. I realize this is a small matter
 since
all I am talking about is how lists are represented as text.
 
checking out the Try Clojure:
 
if you type the following, you get output that matches what you typed
in every case except for lists.
 
Vectors: -- [1 2 3 4]
[1 2 3 4]
 
Maps: -- {:foo bar 3 4}
{:foo bar 3 4}
 
Lists: -- '(1 2 3 4)
(1 2 3 4)  - *INCONSISTENT* why not render this as '(1 2 3 4)
 ...
this would make much more sense to newbies.
 
Sets: -- #{1 2 3 4}
#{1 2 3 4}
 
--
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from

Re: repl output for list seems inconsistent and a holdover from yesteryear

2011-10-27 Thread e
On Thu, Oct 27, 2011 at 7:42 PM, Stephen C. Gilardi squee...@mac.comwrote:


 On Oct 26, 2011, at 7:08 PM, e wrote:

  [1 2 3] is a vector that is not evaluated.  Since there is no overload
 with things that are, there's no need for a special mark.

 If you type [1 2 3] into the REPL it is evaluated. The E part of the REPL
 always runs. Some expressions evaluate to themselves. In this case each
 number evaluates to itself and the vector evaluates to itself:

  user [1 2 3]
  [1 2 3]

 If you have an expression as one of the items in the vector, it will be
 evaluated:

  user [1 (+ 1 1) 3]
  [1 2 3]

 Putting a quote out front suppresses all evaluation:

  user '[1 (+ 1 1) 3]
  [1 (+ 1 1) 3]

  '(1 2 3) is currently a way of say, don't evaluate this list,

 More completely it says, don't evaluate the entire expression that follows
 including any and all sub-expressions

  but it could have been:
 
  '(1 2 3) is a list that is not evaluated.  No loss of generality.  it's a
 special type of list.  One that's not evaluated.  as opposed to a special
 indicator to the repl.

 Current behavior:

  user '(1 (+ 1 1) 3)
  (1 (+ 1 1) 3)

 The behavior you propose:

 user '(1 (+ 1 1) 3)
  (1 2 3)

 ^ excellent explanation right above. +1


 Currently 'x is equivalent to (quote x) for all values of x. With the
 syntax you propose that's no longer true.

 clojure.main/repl allows you to replace the evaluator with any function of
 one argument. If you bring up a repl with, say, lein repl, you can start a
 nested repl with identity as the evaluator and see how things are read
 (which can be interesting):

  % lein repl
  REPL started; server listening on localhost port 46512
  user= (clojure.main/repl :eval identity)
  user= (+ 1 2)
  (+ 1 2)
  user= '(+ 1 2)
  (quote (+ 1 2))
  user= [1 2 3]
  [1 2 3]
  user= [1 (+ 1 1) 3]
  [1 (+ 1 1) 3]
  user= 'x
  (quote x)
  user= x
  x
  user= '[1 (+ 1 1) 3]
  (quote [1 (+ 1 1) 3])
  user= #(+ 3 %)
  (fn* [p1__161#] (+ 3 p1__161#))

 --Steve

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


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

Re: repl output for list seems inconsistent and a holdover from yesteryear

2011-10-27 Thread e
On Thu, Oct 27, 2011 at 8:26 PM, Mark Rathwell mark.rathw...@gmail.comwrote:

  Maybe it would be clearer if I proposed some other, lesser-used chars,
 like
  %(1 2 3 4) or even 1 2 3 4.  That is, I'm not so much saying, this
  needs to be treated as data and not eval'd as I am simply saying, this
 is
  the 'list' data structure as opposed to some other.

 A list data structure and a list code structure are the same.


why wasn't vector chosen for code?


 The
 only difference is that the programmer decides when one should not be
 evaluated.  By creating separate syntax for a list data structure you
 are in essence creating a different structure for lists of data than
 lists of code, and you no longer have a straightforwardly homoiconic
 language.

This seems like a hugely important thing for me to grock, but it is easier
to grock in languages that, say, ONLY have lists.  Otherwise it seems like
code is arbitrarily ONE of the data structures and, therefore is NOT
homoiconic with respect to any other data structure.



  Why is there an assumption that
  code as data means code as lists? Or is there?

 This is the key to everything.  Code is data

yes, fine. but data doesn't always mean list in *my* mind.  But I'm
starting to get that it was chosen to be the same thing in lisps.


 , data is code, they are
 the same structure.  By treating a list of data (integers for example)
 differently than a list of code (function and args), you create a
 situation where code and data are no longer the same thing.

no. code and lists are no longer the same thing.  I see data as a generic
concept . . .a superset, not a different set.  code could be data that I
haven't picked a data structure for, yet.


  That
 trait is a fundamental trait of lisps, and makes things like macros
 much simpler.

I suspected this, too. ok.



 You don't have to call the structure a list, you can
 call it something else if you prefer, but whatever it is called, it
 must be the same structure that defines code and defines data.

But, again, there are plenty of structures that define data differently
then that which was chosen for code.  So why not just have a code
structure.  Again, it already seems broken with respect to other
structures.  Here's some data. It's a vector. Here's *more* data.  It's a
chunk of code.  Ah but it was arbitrarily decided (more from history and
evolution) that *that* data is a list.  Broken.





 On Thu, Oct 27, 2011 at 6:58 PM, e evier...@gmail.com wrote:
 
  On Oct 26, 2011 7:15 PM, Stuart Halloway stuart.hallo...@gmail.com
  wrote:
 
  checking out the Try Clojure:
 
  if you type the following, you get output that matches what you typed
  in every case except for lists.
 
  Vectors: -- [1 2 3 4]
  [1 2 3 4]
 
  Maps: -- {:foo bar 3 4}
  {:foo bar 3 4}
 
  Lists: -- '(1 2 3 4)
  (1 2 3 4)  - *INCONSISTENT* why not render this as '(1 2 3 4) ...
  this would make much more sense to newbies.
 
  Sets: -- #{1 2 3 4}
  #{1 2 3 4}
 
 
  This is an interesting question. Consistency is important, but
 consistency
  with what? Your mental model for what happens at the REPL needs to keep
 the
  R, E, and P steps clearly separate.
 
  Working backward:  the P (Print) prints things in a way that they can be
  read back, where possible:
 
  (read-string [1 2 3 4])
  = [1 2 3 4]
 
  (read-string (1 2 3 4))
  = (1 2 3 4)
 
  (read-string #{1 2 3 4})
  = #{1 2 3 4}
 
  (read-string {1 2 3 4})
  =  {1 2, 3 4}
 
  If the P part of the REPL put a tick in front of lists, they would not
  read back correctly:
 
  (read-string '(1 2 3 4))
  = (quote (1 2 3 4)) INCONSISTENT
 
 
  I see the problem that token  '  is already taken to be short hand for
  quote so to be truly consistent, I might be compelled to argue that
  (read-string '(1 2 3 4)) should, seeing some hypothetical list start
  multi-char token  '(   just like set-start is  #{ , be: = '(1 2
 3
  4).
 
  You'd need two single quotes: ''(1 2 3 4) to get quote '(1 2 3 4) ...
  Wheras (1 2 3 4) means call 1 with ...
 
  I'll have to reread the explanation about the repl phases, but maybe I'm
  wondering if things don't have to be quoted if lists had the syntax I
  describe, and requests for function invocation had a simple paren.  Then
 you
  are not saying, treat this as data, do not eval.  You are just saying,
  see my single quote paren token? That's for lists.
 
  Maybe it would be clearer if I proposed some other, lesser-used chars,
 like
  %(1 2 3 4) or even 1 2 3 4.  That is, I'm not so much saying, this
  needs to be treated as data and not eval'd as I am simply saying, this
 is
  the 'list' data structure as opposed to some other.
 
  Now, if you ever need to read in a program and treat it like data,
 well,
  what structure would you like to put it in? A list? A vector? A string?
 This
  is, indeed, where I am fuzzy on lisps, but it seems like you parse it as
  desired and put it where/how you like it.  Why is there an assumption

Re: repl output for list seems inconsistent and a holdover from yesteryear

2011-10-27 Thread e
I think I understand more now though, everyone.  Thanks.  clojure chose
lists for the data structure for code so lists sort of have a special place
in the language.

Thanks again.

On Fri, Oct 28, 2011 at 1:13 AM, e evier...@gmail.com wrote:



 On Thu, Oct 27, 2011 at 8:26 PM, Mark Rathwell mark.rathw...@gmail.comwrote:

  Maybe it would be clearer if I proposed some other, lesser-used chars,
 like
  %(1 2 3 4) or even 1 2 3 4.  That is, I'm not so much saying,
 this
  needs to be treated as data and not eval'd as I am simply saying, this
 is
  the 'list' data structure as opposed to some other.

 A list data structure and a list code structure are the same.


 why wasn't vector chosen for code?


 The
 only difference is that the programmer decides when one should not be
 evaluated.  By creating separate syntax for a list data structure you
 are in essence creating a different structure for lists of data than
 lists of code, and you no longer have a straightforwardly homoiconic
 language.

 This seems like a hugely important thing for me to grock, but it is easier
 to grock in languages that, say, ONLY have lists.  Otherwise it seems like
 code is arbitrarily ONE of the data structures and, therefore is NOT
 homoiconic with respect to any other data structure.



  Why is there an assumption that
  code as data means code as lists? Or is there?

 This is the key to everything.  Code is data

 yes, fine. but data doesn't always mean list in *my* mind.  But I'm
 starting to get that it was chosen to be the same thing in lisps.


 , data is code, they are
 the same structure.  By treating a list of data (integers for example)
 differently than a list of code (function and args), you create a
 situation where code and data are no longer the same thing.

 no. code and lists are no longer the same thing.  I see data as a generic
 concept . . .a superset, not a different set.  code could be data that I
 haven't picked a data structure for, yet.


  That
 trait is a fundamental trait of lisps, and makes things like macros
 much simpler.

 I suspected this, too. ok.



 You don't have to call the structure a list, you can
 call it something else if you prefer, but whatever it is called, it
 must be the same structure that defines code and defines data.

 But, again, there are plenty of structures that define data differently
 then that which was chosen for code.  So why not just have a code
 structure.  Again, it already seems broken with respect to other
 structures.  Here's some data. It's a vector. Here's *more* data.  It's a
 chunk of code.  Ah but it was arbitrarily decided (more from history and
 evolution) that *that* data is a list.  Broken.





 On Thu, Oct 27, 2011 at 6:58 PM, e evier...@gmail.com wrote:
 
  On Oct 26, 2011 7:15 PM, Stuart Halloway stuart.hallo...@gmail.com
  wrote:
 
  checking out the Try Clojure:
 
  if you type the following, you get output that matches what you typed
  in every case except for lists.
 
  Vectors: -- [1 2 3 4]
  [1 2 3 4]
 
  Maps: -- {:foo bar 3 4}
  {:foo bar 3 4}
 
  Lists: -- '(1 2 3 4)
  (1 2 3 4)  - *INCONSISTENT* why not render this as '(1 2 3 4) ...
  this would make much more sense to newbies.
 
  Sets: -- #{1 2 3 4}
  #{1 2 3 4}
 
 
  This is an interesting question. Consistency is important, but
 consistency
  with what? Your mental model for what happens at the REPL needs to keep
 the
  R, E, and P steps clearly separate.
 
  Working backward:  the P (Print) prints things in a way that they can
 be
  read back, where possible:
 
  (read-string [1 2 3 4])
  = [1 2 3 4]
 
  (read-string (1 2 3 4))
  = (1 2 3 4)
 
  (read-string #{1 2 3 4})
  = #{1 2 3 4}
 
  (read-string {1 2 3 4})
  =  {1 2, 3 4}
 
  If the P part of the REPL put a tick in front of lists, they would not
  read back correctly:
 
  (read-string '(1 2 3 4))
  = (quote (1 2 3 4)) INCONSISTENT
 
 
  I see the problem that token  '  is already taken to be short hand for
  quote so to be truly consistent, I might be compelled to argue that
  (read-string '(1 2 3 4)) should, seeing some hypothetical list start
  multi-char token  '(   just like set-start is  #{ , be: = '(1 2
 3
  4).
 
  You'd need two single quotes: ''(1 2 3 4) to get quote '(1 2 3 4) ...
  Wheras (1 2 3 4) means call 1 with ...
 
  I'll have to reread the explanation about the repl phases, but maybe I'm
  wondering if things don't have to be quoted if lists had the syntax I
  describe, and requests for function invocation had a simple paren.  Then
 you
  are not saying, treat this as data, do not eval.  You are just saying,
  see my single quote paren token? That's for lists.
 
  Maybe it would be clearer if I proposed some other, lesser-used chars,
 like
  %(1 2 3 4) or even 1 2 3 4.  That is, I'm not so much saying,
 this
  needs to be treated as data and not eval'd as I am simply saying, this
 is
  the 'list' data structure as opposed to some other.
 
  Now, if you ever need to read in a program

repl output for list seems inconsistent and a holdover from yesteryear

2011-10-26 Thread e
long long time since I last looked a clojure, but I've never lost
interest and I'm trying to find the time again.

for the short version see *INCONSISTENT*, in the example at the end.

I know what the answer will be here.  Something like you will get
used to it. or it's not important. or no one hardly uses lists
anymore, anyway, since vectors are not purely contiguous.  But, if
you can make things better and it's easy, then why not?

So here's the deal:

I still think the following is only inconsistent because that's how it
was in older lisps.  Specifically, lists had to be quoted so the first
argument wouldn't be called as a function.  I asked long ago (here and
in person) why, then regular functions couldn't require the quote so
the paren could be reserved for the list data structure, and Rich
answered that it'd simply be a pain to have to quote every function
call.  Well, my mind moves slowly.  I'm just now realizing to ask,
Ok, then how about making the list really be defined using the single
quote as part of it just like sets include the sharp to distinguish
them from maps?.  That's a much simpler explanation than saying, you
have to escape them, etc, etc. I realize this is a small matter since
all I am talking about is how lists are represented as text.

checking out the Try Clojure:

if you type the following, you get output that matches what you typed
in every case except for lists.

Vectors: -- [1 2 3 4]
[1 2 3 4]

Maps: -- {:foo bar 3 4}
{:foo bar 3 4}

Lists: -- '(1 2 3 4)
(1 2 3 4)  - *INCONSISTENT* why not render this as '(1 2 3 4) ...
this would make much more sense to newbies.

Sets: -- #{1 2 3 4}
#{1 2 3 4}


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


Re: repl output for list seems inconsistent and a holdover from yesteryear

2011-10-26 Thread e
not necessarily.

[1 2 3] is a vector that is not evaluated.  Since there is no overload with
things that are, there's no need for a special mark.

'(1 2 3) is currently a way of say, don't evaluate this list, but it could
have been:

'(1 2 3) is a list that is not evaluated.  No loss of generality.  it's a
special type of list.  One that's not evaluated.  as opposed to a special
indicator to the repl.

On Wed, Oct 26, 2011 at 6:09 PM, Mark Rathwell mark.rathw...@gmail.comwrote:

 The point to think about here is that functions are also lists, the
 same as your list of integers.  The difference is that one is
 evaluated, the other is not.  That is what the quote is saying: don't
 evaluate me.  The quote is not actually a part of the list. It's just
 the way you tell the reader not to evaluate the list that follows.

 So the question is should all unevaluated forms be preceded with a
 quote in the repl output?  To me that would be more confusing.


 On Wed, Oct 26, 2011 at 5:34 PM, e evier...@gmail.com wrote:
  long long time since I last looked a clojure, but I've never lost
  interest and I'm trying to find the time again.
 
  for the short version see *INCONSISTENT*, in the example at the end.
 
  I know what the answer will be here.  Something like you will get
  used to it. or it's not important. or no one hardly uses lists
  anymore, anyway, since vectors are not purely contiguous.  But, if
  you can make things better and it's easy, then why not?
 
  So here's the deal:
 
  I still think the following is only inconsistent because that's how it
  was in older lisps.  Specifically, lists had to be quoted so the first
  argument wouldn't be called as a function.  I asked long ago (here and
  in person) why, then regular functions couldn't require the quote so
  the paren could be reserved for the list data structure, and Rich
  answered that it'd simply be a pain to have to quote every function
  call.  Well, my mind moves slowly.  I'm just now realizing to ask,
  Ok, then how about making the list really be defined using the single
  quote as part of it just like sets include the sharp to distinguish
  them from maps?.  That's a much simpler explanation than saying, you
  have to escape them, etc, etc. I realize this is a small matter since
  all I am talking about is how lists are represented as text.
 
  checking out the Try Clojure:
 
  if you type the following, you get output that matches what you typed
  in every case except for lists.
 
  Vectors: -- [1 2 3 4]
  [1 2 3 4]
 
  Maps: -- {:foo bar 3 4}
  {:foo bar 3 4}
 
  Lists: -- '(1 2 3 4)
  (1 2 3 4)  - *INCONSISTENT* why not render this as '(1 2 3 4) ...
  this would make much more sense to newbies.
 
  Sets: -- #{1 2 3 4}
  #{1 2 3 4}
 
 
  --
  You received this message because you are subscribed to the Google
  Groups Clojure group.
  To post to this group, send email to clojure@googlegroups.com
  Note that posts from new members are moderated - please be patient with
 your first post.
  To unsubscribe from this group, send email to
  clojure+unsubscr...@googlegroups.com
  For more options, visit this group at
  http://groups.google.com/group/clojure?hl=en

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


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

Re: How to read project.clj file.

2011-08-09 Thread Daniel E. Renfer
On 08/09/2011 05:35 AM, Shantanu Kumar wrote:
 
 
 On Aug 9, 12:22 pm, mmwaikar mmwai...@gmail.com wrote:
 Hi,

 Assuming there are some DB credentials specified in a project.clj file as a
 map, how should I read those credentials in my clojure code -

 1) should I use slurp and then parse that text?
 2) should I (use 'leiningen.core) and then (load-file project.clj)
 3) or something else

 Please let me know the best / idiomatic way to accomplish this.
 
 project.clj is available to Leiningen plugins. Assuming you are open
 to put the DB credentials elsewhere, I'd suggest putting it in another
 file that can be easily discoverable. This idea is implemented in Clj-
 DBCP:
 
 https://bitbucket.org/kumarshantanu/clj-dbcp/overview (jump to the
 section Create DataSource from `.properties` file)
 
 Regards,
 Shantanu
 

When it comes to loading config options, I always use my Ciste library
which has the ciste.config namespace. By default, it looks for a file
named config.clj in the root of the project.

config.clj contains a map with the keys being the environment names and
the values are maps of config options. It needs a bit more work, but it
serves my purposes.

The config function will either return the config map, or it will look
up the passed params in the map.

(use 'ciste.config)

(environment) = :development

(load-config)

(config :database :username) = root



Even if you don't use Ciste (there's a lot of stuff in there that may
not be relevant to your project) The config ns should at least get you
started.
https://github.com/duck1123/ciste/blob/master/src/main/clojure/ciste/config.clj


https://github.com/duck1123/ciste



signature.asc
Description: OpenPGP digital signature


Re: Efficient queue types for Clojure.

2011-06-25 Thread e
interesting.  maybe I can change my interface in this thing I abandoned a
while back: http://code.google.com/p/jc-pheap/

to match that of the contrib, priority map.  I had gotten stuck figuring
out the right interface/usage/idioms for clojure and kinda messed the whole
thing up in later checkins.  Then clojure went to GIT and I pretty much lost
the remaining interesting having started in svn.

but now I have a reason again... if I can ever get a comfortable programming
environment in clojure (never was able to before).  I can see how it works
compared to work others are doing.

thanks.

On Sat, Jan 22, 2011 at 2:14 PM, Mark Engelberg mark.engelb...@gmail.comwrote:

 Clojure already has a built in queue.  The empty queue is:
 clojure.lang.PersistentQueue/EMPTY
 and then you can use all the usual conj/into/pop/peek functions on it.
 For some reason, PersistentQueue is not documented, so new users have
 no reason to know about it until they happen to ask about it here.

 You might be interested to compare your priority queue implementation
 to my priority map in 1.3 alpha's contrib, which also supports
 updating items' priorities.

 As far as I can tell, your priority queue's pop is not O(1), because
 the underlying sorted map doesn't support first in O(1).  It's
 actually O(log32#of priorities).  My priority map is similar, and I
 agree that this behavior is quite fast, but it's worth noting that
 it's not truly O(1).

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


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

Re: Idiomatic way to document defn's

2011-05-13 Thread Steven E. Harris
Paul deGrandis paul.degran...@gmail.com writes:

 (defn create-session!
   Create shared sessions and their associated channel.
   Arguments:

I've found the two-space indentation to be a brittle convention that's not
going to port well to other presentations of the text, or adapt well to
a change in the `doc' function (and `print-doc').

It's weird that a continuation line starting at column zero doesn't
print as being left-aligned with the first line.

-- 
Steven E. Harris

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


Re: Chunking is making my life more difficult.

2010-12-31 Thread Steven E. Harris
ehanneken ehanne...@pobox.com writes:

 I spent a long time debugging some Clojure code yesterday.  The
 essence of it looked similar to this:

 (defn items []
   (mapcat expensive-function (range 0 4000 100)))

 . . . (take 5 (items)) . . .

I tried to distill the problem down by defining a non-chunking range
function (a simple variant), then working outward from there to see what
else is evaluating a surprising number of times.

,
| (defn non-chunked-range
|   [start end]
|   (prn (format In non-chunked-range with %d and %d. start end))
|   (lazy-seq
|(when-not (= start end)
|  (cons start (non-chunked-range (inc start) end)
`

Note that `mapcat` is defined in terms of `map` and `concat`. First
let's confirm that `map` is not eager:

,
| ;; Draws one, and evaluates lazy sequence function twice:
| (take 1
|   (map #(list %)
|(non-chunked-range 0 10)))
`

Experimenting with the argument to `take` shows that the lazy sequence
function is evaluated as expected: a number of times equal to the
argument plus one for the terminal case (n + 1).

Now add `concat` into the mix to make sure it's not eager:

,
| ;; Draws two, and evaluates lazy sequence function three times:
| (concat (take 2 (non-chunked-range 0 10)))
`

That works as expected. Now add `apply` to `concat` as `mapcat` does to
flatten the input lists:

,
| ;; Draws one, and evaluates lazy sequence five times:
| (take 1
|   (apply concat
|  (map #(list %)
|   (non-chunked-range 0 10
`

Whoah! Where did the extra three evaluations of the lazy sequence
function come from? Note that this one calls on the function /five/
times.

Here is the mapping of the argument to `take` and the number of times
the function is called:

 take   calls
    =
 0  5  
 1  5
 2  5
 3  5
 4  6 
 5  7
 ...
 n  n + 2

I read the source for `concat`, but I don't see what it's doing to force
the extra evaluations both below four arguments and the extra one
(yielding n + 2) with four or more arguments. What's responsible for
this difference in behavior?

-- 
Steven E. Harris

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


Re: Regarding The Implementation of 'merge-with'

2010-11-26 Thread Steven E. Harris
Daniel Werner daniel.d.wer...@googlemail.com writes:

 (some identity maps), on the other hand, checks whether there is any
 non-empty map *in the coll of maps*.

By non-empty here, do you really mean non-nil? I don't see how the
identity function would tell you whether any of the maps are empty or
not.

-- 
Steven E. Harris

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


Re: Idiomatic Way to Keep a Variable Private to a Namespace

2010-10-16 Thread Steven E. Harris
ataggart alex.tagg...@gmail.com writes:

 It's fairly common to let over a function, e.g.:

So common, in fact, that Doug Hoyte wrote a book about it:

  Let Over Lambda
  http://www.letoverlambda.com/

-- 
Steven E. Harris

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


Re: precise numbers

2010-10-16 Thread Steven E. Harris
cej38 junkerme...@gmail.com writes:

 (defn float=
   ([x y] (float= x y 0.1))
   ([x y epsilon]
  (let [scale (if (or (zero? x) (zero? y)) 1 (Math/abs x))]
(= (Math/abs (- x y)) (* scale epsilon )

You're scaling epsilon incorrectly here. Epsilon defines the smallest
value that yields a value greater than one when added to one. If you're
not using it along with one, you're using it incorrectly.

What you need to do is scale epsilon by having its exponent match the
value with which you want to use it, while maintaining its mantissa. The
C library offers functions ldexp()¹ and frexp()² to split and scale the
exponent of a floating point number, respectively; Common Lisp offers
DECODE-FLOAT³ and SCALE-FLOAT for the same purpose.

I don't know of any standard functions in Java -- or Clojure -- that
allow one to destructure a floating point number like this. It's
possible to use Float#floatToRawIntBits(), an understanding of IEEE 754,
and tweezers to get there.

If you assume you have a function called `scaled-epsilon' that accepts
the exemplar value with which you intend to use epsilon,

  (defn scaled-epsilon [n] ...)

you can use the following function `same?' to compare your floating
point values, assuming they're nonnegative:

,
| (defn same?
|   [m n]
|   (if ( n m)
|   (sufficiently-close? n m)
|   (sufficiently-close? m n)))
| 
| (defn- sufficiently-close?
|   [smaller larger]
|   (or (zero? larger)
|   (if (zero? smaller)
|   ( larger (scaled-epsilon 0.0)))
|   (zero? (- 1 (/ smaller larger)
`

Note too that scaling epsilon must take into account whether you intend
to add it or subtract it from some companion number. It's common to use
the word epsilon to mean some fudge factor without considering what
the value really means for a floating point number. Indeed, using it
properly in Java is still too difficult. 


Footnotes: 
¹ http://www.dinkumware.com/manuals/?manual=compleatpage=math.html#frexp
² http://www.dinkumware.com/manuals/?manual=compleatpage=math.html#ldexp
³ 
http://www.lispworks.com/documentation/HyperSpec/Body/f_dec_fl.htm#decode-float
  http://www.lispworks.com/documentation/HyperSpec/Body/f_dec_fl.htm#scale-float

-- 
Steven E. Harris

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


Re: Idiomatic Way to Build String or Simply Use StringBuilder

2010-09-30 Thread Steven E. Harris
Mark Engelberg mark.engelb...@gmail.com writes:

 str uses a string builder behind the scenes, so it's efficient this
 way.

If the `str' implementation didn't take the input sequence to be lazy,
it could figure out how long the resulting string needed to be, and
construct the StringBuilder using the single-integer constructor,
ensuring that no reallocation and copying occurs. Some temporary
allocation would still be necessary to hold the Object-to-String
projection, as `str' calls Object#toString() on each argument, rather
than assuming the arguments are already of type String.

-- 
Steven E. Harris

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


Re: Literal collection of numbers - prefer list or vector?

2010-09-26 Thread Steven E. Harris
ataggart alex.tagg...@gmail.com writes:

 Vectors also permit evaluation of the literal collection's elements:

 user= [(+ 1 2) (+ 3 4)]
 [3 7]
 user= '((+ 1 2) (+ 3 4))
 ((+ 1 2) (+ 3 4))

That's a false distinction. You used `quote' rather than
`list'. Macroexpand your form to see:

,
| user (quote ((+ 1 2) (+ 3 4)))
| ((+ 1 2) (+ 3 4))
`

Quote is not a list constructor. It simply returns what the reader had
constructed without evaluating it, and in this case, the reader had
constructed a list.

What you should have supplanted the vector literal reader with was the
`list' function:

,
| user (list (+ 1 2) (+ 3 4))
| (3 7)
| user (vector (+ 1 2) (+ 3 4))
| [3 7]
`

-- 
Steven E. Harris

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


Re: Literal collection of numbers - prefer list or vector?

2010-09-26 Thread Steven E. Harris
David Sletten da...@bosatsu.net writes:

 Umm, kind of...The single quote is a macro character not a real
 macro.

And I didn't say it was a macro. It's a macro character tied to a reader
macro, and it participates in read-time macroexpansion.

,
| user (quote (a 'b))
| (a (quote b))
`

[...]

 The reader silently converts 'pung to (quote pung) prior to
 evaluation, so you have to come at it in a roundabout way:

That's not conspiring; that's read-time macroexpansion working as
intended.

-- 
Steven E. Harris

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


Re: Why so?

2010-09-03 Thread Steven E. Harris
David Nolen dnolen.li...@gmail.com writes:

 Clojure functions categorized: http://clojuredocs.org/quickref/Clojure%20Core

Wow, that is very nice -- especially the expandable view of the
implementation source.

-- 
Steven E. Harris

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


Re: What is the reason Lisp code is not written with closing parenthesis on new lines?

2010-08-18 Thread Daniel E. Renfer
On 8/18/10 1:32 PM, Brian Goslinga wrote:
 Putting them on separate lines put the focus on the wrong element of
 the code.  You do not want to be focusing on the parentheses, you want
 to be focusing on the structure of the code.  The idiomatic lisp
 formatting style uses indentation to reveal the large scale structure
 of the code, and so the parentheses can be neatly tucked away.  With a
 little experience, the parentheses will start to fade from view.
 
 Additionally, putting them on separate lines waste vertical space, and
 you should be using an editor that supports paren matching so you
 don't need to count them.
 

Generally, when I am working on a function, I will put the closing
parens anywhere with a ton of whitespace all around. Once I'm done with
the function, I make sure to delete all of the excess breaks so that
it's a nice neat block of code.

Using paredit in emacs makes it really easy to handle the closing
parens. I'm sure there are other good tools for the other editors.



signature.asc
Description: OpenPGP digital signature


Re: Protocols and default method implementations

2010-08-14 Thread Steven E. Harris
Matthew Phillips mattp...@gmail.com writes:

 ;; A node has a data attachment and (possibly) children
 (defprotocol Node
   (data [n])
   (children [n]))

 (deftype SimpleNode [d]
   Node
   (data [n] d)
   (children [n] []))

 ;; In version 2, I add want to add pretty-printing

 (defprotocol PrettyPrintableNode
   (pretty-print [n]))

 ;; Make anything potentially pretty-print'able
 (extend-type Object
   PrettyPrintableNode
   (pretty-print [n] (str A node:  (data n

I'm confused by the mixture of formality and looseness here.

When you extend this way, binding this `pretty-print' implementation to
arguments of type Object, you're implicitly requiring that argument n
satisfies the protocol Node -- because you call the `data' function on
it. But if the function `data' would work on any kind of Object, then so
too would any call to `pretty-print', right? Should the call to `data'
within the `pretty-print' definition above require some mention of
protocol Node?

In other words, what's the difference between using `extend-type' here
on Object and just writing

,
| (defn pretty-print
|   [n]
|   (str A node:  (data n)))
`

My experiments in the REPL don't show any difference in behavior.

Being able to define a normal `pretty-print' function above differs from
the generic function system in Common Lisp. There, if one has defined a
generic function with `defgeneric', and one later tries to define a
normal function with the same name, the normal function replaces the
generic function, and the compiler may emit a warning. Working the other
way, though, one may not define a generic function -- using `defgeneric'
or `defmethod' -- if the function name is already bound to a normal
function, macro, or special operator.

Is there supposed to be a difference between the normal function
`pretty-print' I wrote above and the function defined in the
`extend-type' form quoted above?

-- 
Steven E. Harris

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


Re: Idea for personal Clojure project

2010-07-28 Thread Daniel E. Renfer
On 7/28/10 5:34 PM, Mark Engelberg wrote:
 Wordnet is the main existing thing that comes to mind as related to your
 idea.
 

You might also want to look into Freebase. Here's a Clojure client you
can use to query their data. http://github.com/rnewman/clj-mql



signature.asc
Description: OpenPGP digital signature


Re: persistent LRU cache (request for input)

2010-07-18 Thread Steven E. Harris
Peter Schuller peter.schul...@infidyne.com writes:

 I can turn 'get' into 'peek' and have another function that more
 specifically advertises, by its name, that it produces both a value
 and a new cache. That only helps naming though, and not usability of
 said function.

Yes, and though it does so for a completely different reason, there's
precedence for this in the Standard C++ Library's stack¹, queue², and
vector³ class templates (as well as some other containers). There,
reading (e.g. std::queue::front()) and mutating (e.g. std::queue::pop())
are kept separate, because mutating exposes us to exception safety
concerns; for popping an item off the front of a queue, trying to return
a value that needs to be copy-constructed could trigger an error /after/
the underlying container has been mutated to no longer contain that
value.

What's less clear to me here, though, is how a caller would know when to
call on the mutating LRU adjuster function. If the peek function tells
him what he needed to know, you're still left with the odd contract of
needing him to call some other function to actually note his interest's
effect on the LRU ordering.


Footnotes: 
¹ 
http://www.dinkumware.com/manuals/default.aspx?manual=compleatpage=stack.html#stack
² 
http://www.dinkumware.com/manuals/default.aspx?manual=compleatpage=queue.html#queue
³ 
http://www.dinkumware.com/manuals/default.aspx?manual=compleatpage=vector.html#vector

-- 
Steven E. Harris

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


Re: persistent LRU cache (request for input)

2010-07-17 Thread Steven E. Harris
Peter Schuller peter.schul...@infidyne.com writes:

   lru-peak - [value]

I take it you meant peek, not peak.

[...]

 One possibility I was thinking of was that, since the expected use
 case of an LRU cache is so specific, it may be acceptable to have the
 lru library itself provide a side-effect aware interface directly.

The LRU aspect of the cache is no business of those using the get and
put parts of the interface. Those callers should just think they're
using an associative array, dictionary, map, or whatever you want to
call it. That having called get may influence what gets evicted next
from some other function isn't germane to the caller's interest.

Unless you're willing to use something like the State monad to represent
(and help hide) the side effects of calling your get function, I think
you're better of making no claim about what get does beyond its normal
contract: promise only that it returns the value mapped to the given
key, if any. This data structure doesn't seem like a good fit for a
functional-style interface.

-- 
Steven E. Harris

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


Re: auto-indent in Counterclockwise

2010-07-08 Thread Steven E. Harris
Laurent PETIT laurent.pe...@gmail.com writes:

 When you say that it's hard ... '[' and ']' ..., you're talking
 about the original paredit.el in emacs?

Actually, I was talking both about the current Emacs Lisp editing
library (where `move-past-close-and-reindent' is defined) and the most
recent paredit.el library available for download.

 Or you saw a deficiency in counterclockwise ?

No, I wasn't complaining about Counterclockwise. Rather, I was noting
that the /complete/ behavior of `move-past-close-and-reindent' is hard
to mimic.

-- 
Steven E. Harris

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


Re: auto-indent in Counterclockwise

2010-07-07 Thread Steven E. Harris
Laurent PETIT laurent.pe...@gmail.com writes:

 But to make it really clear: move-past-close-and-reindent is exactly
 what counterclockwise's is doing in Strict edition mode (not totally
 true concerning the reindentation, currently in ccw it is only
 reorganizing closing brackets by removing extra spaces, not
 reindenting lines).

I see. That's good to hear.

It's hard to know when you've really met the Emacs capability
there. That function does so many things right that I can't bear editing
Lisp code without it. That it's hard to adapt it to work with symmetric
brackets (for Clojure's '[' and ']') is disappointing, and I have found
the paredit package to be not much better on that front (having
difficulty with balancing '{' and '}'). It has its own set of oddities.

-- 
Steven E. Harris

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


Re: auto-indent in Counterclockwise

2010-07-06 Thread Steven E. Harris
Laurent PETIT laurent.pe...@gmail.com writes:

 I think it's a good feature, *if* typing the closing bracket/paren just
 resulted in cursoring over the one that'd already been inserted.

 ?

See the Emacs function `move-past-close-and-reindent'. It works as the
obvious counterpart to the function `insert-paretheses'.¹


Footnotes: 
¹ http://www.cliki.net/Editing%20Lisp%20Code%20with%20Emacs

-- 
Steven E. Harris

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


Re: Enhanced Primitive Support

2010-06-20 Thread Steven E. Harris
David Nolen dnolen.li...@gmail.com writes:

 Using loop/recur is already the beginning of code smell for anything
 that is not performance sensitive.

[...]

In your arity-overloaded example, is there any runtime cost to figure
out which of the two overloads to choose each time `recur' evaluates?

-- 
Steven E. Harris

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


Re: Mac Emacs users: which version do you prefer (Aquamacs, Carbon Emacs, other?)

2010-06-12 Thread Steven E. Harris
Moritz Ulrich ulrich.mor...@googlemail.com writes:

 Aquamacs integrates nice, but it changes many emacs keybinding
 per-default and makes it hard to change them, which is a no-go for me.

Here's what I use (so far) to beat it back into shape:

(cua-mode 0)
(transient-mark-mode 1)
(pending-delete-mode 1)

;; I'm not ready to accept the separation of the Emacs kill ring and
;; the system clipboard.
(osx-key-mode 0)

;; Revert the binding for `recentf-open-files' defined in
;; 
/Applications/Aquamacs.app/Contents/Resources/lisp/aquamacs/macosx/aquamacs-menu.el:
(global-set-key \C-x\ \C-r 'find-file-read-only)

-- 
Steven E. Harris

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


Re: review the clojure.string code

2010-05-30 Thread Steven E. Harris
Why do some of the functions use StringBuilder (no internal
synchronization) and some use StringBuffer (provides internal
synchronization). Using the latter is probably a mistake.

The first function -- reverse -- uses StringBuilder#reverse() to reverse
the character sequence in place, and then calls StringBuilder#toString()
to yield a String. Why is the final step necessary? Since StringBuilder
implements CharSequence, isn't it sufficient to just return the
StringBuilder? That's what the function signature promises. Calling
toString() makes yet another copy of the data, so it's best avoided.

Some of these functions construct instances of class StringBuilder using
its default constructor, which gives it a default capacity. But most of
the functions also know at the outset some reasonable size for the
buffer. For instance, function `replace-first-by' could reasonably use
the length of its argument s as the size of the buffer, even though
the replacement for some matched substring may increase the overall
length.

Why does function `replace-first' unconditional call
CharSequence#toString() on its argument s, when in several cases just
using s as a CharSequence would be fine. Again, calling
CharSequence#toString() might make a copy of the data, depending on
whether the CharSequence was actually a String or something like a
StringBuilder.

The implementation of a function like `trim' could be more efficient,
given that it's allowed to return a CharSequence. You can construct a
StringBuilder of length equal to the source CharSequence, then walk the
source sequence from the beginning, skipping over all whitespace,
copying the non-whitespace characters, repeating until you hit the end
of the source string. The right trim behavior is a little tricky, as
you have to suspend the copying upon encountering whitespace, but but
back up and copy that whitespace upon encountering something else before
the end of the source string. Alternately, just walk backward from the
end of the source string.

The bonus is that you only copy the data once. With the current
implementation, calling CharSequence#toString() might copy the data
once, and calling String#trim() will copy it again.

Rounding out the review, function `trim-newline' doesn't have to call
toString() on the CharSequence yielded by CharSequence#subSequence(), as
it already promises to return a CharSequence.

Most Java code poisons its string manipulation efficiency by always
promising to return String rather than CharSequence. You've done better
in your signatures here, so I'm just encouraging you to avoid String and
the extra copies it forces.

-- 
Steven E. Harris

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


Re: Clojure Concurrency Screencast Available

2010-05-01 Thread e
interesting so far.  the format I first tried didn't work on my droid, but
no big deal.

one, kind-of Eureka moment I just had, which is somewhat blasphemous, I
guess:

Craig is going through how a vector is [1 2 3] but a list has to be '(1 2
3)?  Well, that may be one of the turn-offs people have from other
languages.

Can you imagine how disruptive it would be at this point to do it the other
way around?  If you were starting out today without any Lisp baggage, it
seems TOTALLY obvious to me that lists would have been (1 2 3), and the
*calling of a function* would have been the different thing ... now that
these other data structures represent themselves symbolically (vectors,
sets, maps).

The quote symbol (or other) should have been to call the function.  That
would make much more sense, but I doubt making a syntax like that would earn
one many friends.

Oh well, I'll keep watching.  Starting out very nice.


On Sat, Apr 10, 2010 at 3:06 PM, Craig Andera craig.and...@gmail.comwrote:

 Mobile downloads are available now. Sorry about the delay. The refs module
 is also up, so that's five of six. Part six by mid next week.


 On Sat, Apr 10, 2010 at 9:26 AM, Craig Andera craig.and...@gmail.comwrote:

 Right, good point: I should have seen that coming given the target
 audience. :)

 Within a few hours, a mobile download link will appear with wmvs and
 mp4s in a variety of resolutions so you can watch these offline on the
 device of your choosing. The conversion lags the rest of the process a
 little bit, but I'm told the upload is in progress now.

 Hope that helps.


 On Fri, Apr 9, 2010 at 7:22 PM, Jeff Heon jfh...@gmail.com wrote:

 I must say I appreciate video sharing sites like blip.tv and Vimeo
 that allows one to download and watch their videos offline.
 Very practical for those commuting and using portable devices 8)

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

 To unsubscribe, reply using remove me as the subject.



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


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

Re: Clojure Concurrency Screencast Available

2010-05-01 Thread e
And ... in another Ah-ha based on an email I just received on this subject
... what should really be said here is that there should be an explicit
symbol to say that the first argument of the list is receiving special
treatment (the words of the emailer).  Well, that got me thinking:

Now I know what the symbol should really be!  It should be the number zero
(or one if you prefer one-based things).  so (+ 1 2) is just three symbols,
but 0(+ 1 2) means the first argument is the function.  That makes 1(1 + 2)
easy.  Oh and while we are at it, then things like all the funky, confusing
arrows are easy, too.  You could have t(...) for thread and tf(...) for
thread first (if that's different from thread) ... tl(...) for thread
last.   and you could have n(...) for postfix.  wow.  this seems powerful
to me, and more obvious.

Another choice would have been to use something else for lists, like 1 2
3, but I guess that would have looked a little too much like templates or
html (more blasphemy).

On Sat, May 1, 2010 at 11:30 AM, e evier...@gmail.com wrote:

 interesting so far.  the format I first tried didn't work on my droid, but
 no big deal.

 one, kind-of Eureka moment I just had, which is somewhat blasphemous, I
 guess:

 Craig is going through how a vector is [1 2 3] but a list has to be '(1 2
 3)?  Well, that may be one of the turn-offs people have from other
 languages.

 Can you imagine how disruptive it would be at this point to do it the other
 way around?  If you were starting out today without any Lisp baggage, it
 seems TOTALLY obvious to me that lists would have been (1 2 3), and the
 *calling of a function* would have been the different thing ... now that
 these other data structures represent themselves symbolically (vectors,
 sets, maps).

 The quote symbol (or other) should have been to call the function.  That
 would make much more sense, but I doubt making a syntax like that would earn
 one many friends.

 Oh well, I'll keep watching.  Starting out very nice.


 On Sat, Apr 10, 2010 at 3:06 PM, Craig Andera craig.and...@gmail.comwrote:

 Mobile downloads are available now. Sorry about the delay. The refs module
 is also up, so that's five of six. Part six by mid next week.


 On Sat, Apr 10, 2010 at 9:26 AM, Craig Andera craig.and...@gmail.comwrote:

 Right, good point: I should have seen that coming given the target
 audience. :)

 Within a few hours, a mobile download link will appear with wmvs and
 mp4s in a variety of resolutions so you can watch these offline on the
 device of your choosing. The conversion lags the rest of the process a
 little bit, but I'm told the upload is in progress now.

 Hope that helps.


 On Fri, Apr 9, 2010 at 7:22 PM, Jeff Heon jfh...@gmail.com wrote:

 I must say I appreciate video sharing sites like blip.tv and Vimeo
 that allows one to download and watch their videos offline.
 Very practical for those commuting and using portable devices 8)

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

 To unsubscribe, reply using remove me as the subject.



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




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

Re: Clojure Concurrency Screencast Available

2010-05-01 Thread e
doesn't sound like you are misunderstanding.  Data is data, first and
foremost in that model.  you have to work to turn something into a function.
 other than functions, everything is data.  That's the JSON way, for sure.
 When something is a function, you see things like eval and function in
javascript, at least.  But they only have two types, arrays and objects
(dictionaries).

On Sat, May 1, 2010 at 11:06 PM, Alex Osborne a...@meshy.org wrote:

 e evier...@gmail.com writes:

  Can you imagine how disruptive it would be at this point to do it the
  other way around?  If you were starting out today without any Lisp
  baggage, it seems TOTALLY obvious to me that lists would have been (1
  2 3), and the *calling of a function* would have been the different
  thing ... now that these other data structures represent themselves
  symbolically (vectors, sets, maps).

 Interesting, although in the case of idiomatic Clojure it's actually
 very rare to want to use a list literal.  Most of the places you'd use a
 list literal in other lisps, a vector probably makes more sense in
 Clojure.  I'm also not sure the code-is-data thing works so well when
 you reverse quotation like that as it means you'd have quotes on every
 nested level instead of just the outside, which would make macros more
 difficult to write (at least without any other changes), but I may be
 misunderstanding your idea.

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


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

Re: clojure 1.2 seq fn enhancement FAQ

2010-04-30 Thread Steven E. Harris
Phil Hagelberg p...@hagelb.org writes:

 Actually I do consider sets to have keys, since internally they are
 implemented using maps, so the exact same semantics apply for their
 lookup. They're just maps where the key and value are the same thing:

But that implementation is one of convenience, of possibly admirable
laziness, and it's none of our business. A key is something apart from a
value it refers, but in sets, there's no separate value being referred
to. The value is the only thing in play.

Where we get hung up in software is with the flexibility to define
equality or sufficient sameness in set implementations by taking
only part of the stored values into account. The same idea doesn't exist
in the mathematical view of sets. Our software would be much clearer if
sets didn't tolerate these key comparison views, and would instead
force one to use a map in cases where such a key comparison view
(being something less than the value itself) is necessary.

-- 
Steven E. Harris

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


Re: Why I have chosen not to employ clojure

2010-03-23 Thread e
I'm starring that post.  Still haven't gotten Aquamacs working with
clojure.  will try yet again tonight.

On Tue, Mar 23, 2010 at 3:28 PM, Carson c.sci.b...@gmail.com wrote:

 I second Lee's thought -- my work as a grad student is AI research,
 not application development.  I'm glad I discovered Incanter's package
 (three lines of instructions [1]) that allows me to run a Swank server
 that I can easily connect to from Emacs (and Slime from the Emacs end
 can be easily installed thru Elpa).  The part about getting Swank/
 Slime easily going achieves the threshold on the editor front.

 [1] from http://data-sorcery.org/2009/12/20/getting-started/
 $ git clone git://github.com/liebke/incanter.git
 $ cd incanter
 $ mvn install

 then $ bin/clj to get a repl on the terminal or $ bin/swank to start
 up a swank server.

 For me, if it takes more than three lines on the terminal, it's just
 too much. :)

 So labrepl sounds interesting from what I read here (especially as it
 includes Incanter?).  It'd be great if it also has Swank as part of it
 so Emacs can connect to it (or does it already?).

 Thanks!
 Carson


 On Mar 23, 11:53 am, Lee Spector lspec...@hampshire.edu wrote:
  I like where this is going but I would suggest that there's a significant
 audience (including me and most of my students) in what we might call
 category A.01: Want to explore and even do some real work, but not
 necessarily work involving deploying apps, connecting to databases, working
 with third party code, or anything else that requires a full-featured
 production environment or project management system. A working REPL with
 access to contrib and a classpath that allows load to work (all of which I
 can get pretty painlessly with ClojureX) is *almost* enough, but the 0.01
 extra that makes an enormous difference is an editor with the minimal
 functionality of clojure-aware indentation and bracket matching.
 
  I'm intrigued by what I've read here about labrepl, but can someone tell
 me if it's possible that the lein installation step will mess up my existing
 setup in any way? Not knowing anything about lein, and having had a
 confusing time creating my setup that now works (with ClojureX + slime), I
 don't want to endanger it. This is part of the reason that I (and I presume
 others who have expressed similar sentiments) really like the idea of a
 getting started package for which the installation process is literally
 just download and double click or maybe download, unzip, and double
 click. (And if you don't like it, throw away what you downloaded and the
 rest of your system will be unchanged.)
 
  For me the functionality threshold for such a package, which would not
 only get me started but allow me to do serious work (AI research, not
 application development) and teach using Clojure, is: a REPL, access to
 contrib, a classpath that lets load find my source files, and a
 clojure-indenting, bracket-matching editor. Anything else is gravy, but most
 of the existing getting started setups fall short of my threshold at least
 on the editor front.
 
   -Lee
 
  On Mar 23, 2010, at 11:30 AM, Stuart Halloway wrote:
 
 
 
 
 
   I think it is important to be clear about the difference between:
 
   (A) exploring Clojure (non trivially, including interesting Java
 libraries)
 
   (B) deploying Clojure into production.
 
   I nominate the labrepl (http://github.com/relevance/labrepl) as a
 solution for (A). It already includes interesting libraries (e.g. compojure,
 incanter), and it has instructions for working with different IDEs (which I
 hope the community will improve upon).
 
   I don't think there is, or needs to be, a one-size-fits-all solution
 for (B). That's what the Java ecosystem is for. Plus, beginners don't need
 (B).
 
   Stu
 
   So perhaps it would be worthwhile to create, like jruby, a single zip/
   tgz file containing clojure, clojure-contrib, and a reasonable bin/clj
   file that will find at least the core clojure jar files on its own? I
   don't see how you're going to actually deploy any clojure apps, or
   connect to a database, or really use any third party code at all
   without understanding how java's classpath works but at least you can
   get a REPL going.
 
   --
   You received this message because you are subscribed to the Google
   Groups Clojure group.
   To post to this group, send email to clojure@googlegroups.com
   Note that posts from new members are moderated - please be patient
 with your first post.
   To unsubscribe from this group, send email to
   clojure+unsubscr...@googlegroups.comclojure%2bunsubscr...@googlegroups.com
   For more options, visit this group at
  http://groups.google.com/group/clojure?hl=en
 
   To unsubscribe from this group, send email to clojure+
 unsubscribegooglegroups.com or reply to this email with the words REMOVE
 ME as the subject.
 
   --
   You received this message because you are subscribed to the Google
   Groups Clojure group.
   To post to this group, 

Re: Why I have chosen not to employ clojure

2010-03-22 Thread e
think about the difference between putting flash or python on a machine
compared to clojure.  there's more of a system-level path feel to those
things (even though each user can have their own environment).  I mean, you
can add a clj script to your path and get the same effect, but that's what's
different.  He's not talking about someone messing around with a language
... he's talking about trying to imagine that the language is now part of
the system.  Again, Fantom sort of has this feel.  Part of the DEFAULT
instructions is to mess with your path and get things going.  Check out the
Fantom website.  So simple and straight forward and inviting.

On Sun, Mar 21, 2010 at 11:07 PM, Seth seth.schroe...@gmail.com wrote:

 I hate to feed trolls, but this is a solid example of passive-
 aggresive behavior. Also, ignoring plausible sounding, spell-checked
 diatribes is bad.

 The installation of one or two jar files from a Maven repository is
 par for the JVM course. Deployment? Works on any reasonable JVM out
 there. Could the install/deploy behavior be improved? Sure, but try
 targeting something less ubiquitous than ant. Slackware more modern
 than Ubuntu??

 Contrasting Clojure with Flash on Ubuntu really takes the cake. Flash
 has never had a good reputation outside of Windows. Also, either the
 poster is running as root (!) or has somehow forgotten a very
 important su/sudo between steps 2 and 3. Either way, no sysadmin has
 to be convinced.

 Wresting with pigs is bad because you get dirty and the pig likes it.

 On Mar 21, 2:42 pm, Tim Johnson t...@johnsons-web.com wrote:
  I have evaluated clojure for the last couple of days, and it is both my
 own
  professional decision and my recommendation to the professional
 organizations
  that I belong to and report to that clojure is not ready for prime time.
 
  Before any of you think that I am a disgruntled newbie turned troll, know
  the following:
 
  1)As soon as I see the copy of this email in my clojure mailbox, I will
  unsubscribe from this mailing list, delete the clojure mailbox and I will
 not
  be following up in any way.
 
  2)In as much as clojure is a new programming language with a small but
  enthusiastic user base and a brilliant developer I confess to a certain
 deja vu
  here. That would be rebol 10 years ago. Brilliantly conceived,
 brilliantly
  designed by one of the best programmers on the planet. Never went
 anywhere.
  I've used rebol for 10 years steadily and made a lot of money with it,
 but
  there is almost 0 demand for rebol programmers out there.
 
  3)Although I may be a noob with it comes to clojure and even more of a
 noob
  when it comes to java, I have been a professional analyst and programmer
 for 21
  years and own my own company. Many seasoned programmers, analysts and
 system
  adminstrators look at a new system as something to employ. As a front
 end for
  java, I do not consider clojure to be employable.
 
  I think that clojure is brilliantly conceived and it is clear from what I
 have
  read of Rich Hickey's words that his vision is right in the same channel
 with
  mine, but that is not the problem. The fact that I respect the developer
 and
  the product is the reason that I have taken this time to write this
 email.
 
  The reason I choose NOT to employ clojure can be summed up in three
 words.
  ---
  Install and deploy.
  ---
 
  I consider this to be clojure's fatal weakness. Certainly I can get
 clojure up
  and running, but selling clojure to a sysadmin is going to be a problem
 at
  this time. There was a time when PHP was NOT present on virtually all
 webservers.
  PHP got it's foot in the door because it was very easy to deploy.
 
  Consider the two threads that I started up - one is titled Web
 programming in
  Clojure - there's the good stuff. Generous reponse, lots of input.
 
  The other one is titled Installation issues on slack 13.0 (ant?). This
 where
  it all falls apart.
 
  Sadly, this is like the first impression and we all know how lasting
 first
  impressions are. In fact as you can see, the thread ended with no
 resolution.
  I'm sorry to pick on steve but his response is a case study
 
  * Steve stephen.a.lind...@gmail.com [100320 05:24]:
 
   Reading the getting started page on the website will get you further
   still :http://clojure.org/getting_started
 
  Sadly inadequate! Check out the comparable kawa resources and
 instructions for
  a better example.
 
   If you do need ant then a more modern distro will make your life much
   easier (eg. apt-get install ant).
 
  Again, so inadequate. I also use ubuntu. Have for years. apt-get is a
 thing
  of beauty. When it works. And bye the way, slackware is much more modern
  when it comes to up-to-date build tools. So know I not only have to
 sell
  clojure to the sysadmins, I have to sell them ubuntu too? Good luck with
  that!
 
  Here's how I installed the flash player on my system.
  1)Downloaded 

Re: Why I have chosen not to employ clojure

2010-03-22 Thread e
On Mon, Mar 22, 2010 at 1:26 AM, cej38 junkerme...@gmail.com wrote:

 I am a physicist by training and practice, this means that I am an
 expert on Fortran 95.  To say my exposure to Java is minimal would be
 generous.  And until last year when I heard about Clojure from a
 friend, I thought LISP was a speech impediment.

 Setting up Clojure was a MAJOR problem for me, what with getting
 path's and classpaths right. (Figuring out what a classpath is was a
 challenge.)  If it wasn't for the very patient help of a CS friend of
 mine, I would not have figured it out.

 I think the documentation assumes that the user is comfortable with
 Java.  I feel like I am being asked to learn Java so that I can learn
 Clojure.


Amen!  I can understand why this was the initial road to get functionality
going quickly, but I hope this goes away.



 I am now an avid Clojure user, but there really does need to be better
 descriptions of how to set Clojure up on the website.


 On Mar 21, 4:37 pm, Quzanti quza...@googlemail.com wrote:
  Reading his post I got the impression he was a bit of an egocentric (a
  bit more information about himself than was relevant), those sorts
  tend to overreact.
 
  However I can imagine the whole just bung the jar file on your
  classpath thing wouldn't make much sense for a java newbie. It may
  highlight the need for some special 'getting started' documentation
  for Lisp programmers who have never used java, which I understand to
  be one target audience of clojure.
 
 
 
 
 
   I don't understand the complaints about installing Clojure. As far as I
 know
   there's nothing required to 'install' Clojure beyond downloading the
   clojure.jar, other than I guess having a working Java installation.

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

 To unsubscribe from this group, send email to clojure+
 unsubscribegooglegroups.com or reply to this email with the words REMOVE
 ME as the subject.


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

To unsubscribe from this group, send email to 
clojure+unsubscribegooglegroups.com or reply to this email with the words 
REMOVE ME as the subject.


Re: Why I have chosen not to employ clojure

2010-03-21 Thread e
there's a positive reason to say all that stuff as if to say,  and it's not
that I'm a slouch.  I have been able to succeed with other technology.
 I've personally had tons of trouble getting going with clojure, and I use
java all the time.  I think the ideas in clojure are awesome, and I like the
language, but if folks have never looked at Fan/Fantom ... as far as getting
into it, *that's* about the gentlist you can get into anything.  The website
was written in Fantom, it's a one stop shop for getting started ... not that
I like that language better or anything, but, seriously ... that's a fun
exercise.  It's very inviting and welcoming and I wish that a page could be
taken from that approach -- I think he wouldn't have had any of the same
opinions if it had.

And I realize I'm not being very concrete: I'd had plans to write up what I
thought some specific differences were.  Now I'm just left with an
impression ... an impression that Fantom wants you to LOVE that language . .
. .and an impression of clojure that you have to want to love clojure (so
then you have to make a lot of complicated arguments as to why that is so,
which, by the way, I think are beautifully presented in Clojure In Action).

And don't get me started on trying to get emacs or vi all hooked up on my
mac.  I've never succeeded.  Summary: I agree to some extent.  clojure is
awesome.  I wish I could use it at work, but it's an incredibly hard thing
to sell.

On Sun, Mar 21, 2010 at 4:37 PM, Quzanti quza...@googlemail.com wrote:


 Reading his post I got the impression he was a bit of an egocentric (a
 bit more information about himself than was relevant), those sorts
 tend to overreact.

 However I can imagine the whole just bung the jar file on your
 classpath thing wouldn't make much sense for a java newbie. It may
 highlight the need for some special 'getting started' documentation
 for Lisp programmers who have never used java, which I understand to
 be one target audience of clojure.

 
  I don't understand the complaints about installing Clojure. As far as I
 know
  there's nothing required to 'install' Clojure beyond downloading the
  clojure.jar, other than I guess having a working Java installation.
 

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

 To unsubscribe from this group, send email to clojure+
 unsubscribegooglegroups.com or reply to this email with the words REMOVE
 ME as the subject.


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

To unsubscribe from this group, send email to 
clojure+unsubscribegooglegroups.com or reply to this email with the words 
REMOVE ME as the subject.


Why do functions in the state monad only accept one value?

2010-03-16 Thread Steven E. Harris
I've been comparing the definition of the Clojure's state monad --
state-m in clojure.contrib.monads -- to definitions I've found
elsewhere, and there's a facet of the Clojure definition that's
puzzling: Why do monadic functions in state-m only accept one argument
(a basic value) and return a monadic value (a function accepting a
state), as opposed to accepting both the basic value and a state?

Looking at the definitions for the state monad in Haskell, it seems
ambiguous as to whether the monadic functions accept one or two values,
but then functions in Haskell can all be curried, so it's hard to tell.

The paper Monads for functional programming¹ by Philip Wadler shows
the following definition of the bind operator on page 9:

  m * k = \X.let (a, y) = m x in
 let (b, z) = k a y in
 (b, z)

Note the application of function k is shown as

  k a y

where a is the basic value resulting from m and y is the state as
updated last by m. This definition suggests that function k doesn't
make much sense without these two arguments supplied. Again, though,
this is Haskell, so supplying multiple arguments at once doesn't mean
much.

In the Haskell tutorial's article The State monad², the definition
looks more like Clojure's:

  (State x) = f =
State $ \s - let (v,s') = x s in runState (f v) s'

There we see monadic function f applied to basic value v, and then
the result applied to the pending state s'.

Clojure's definition is as follows:

  (fn m-bind-state [mv f]
(fn [s]
  (let [[v ss] (mv s)]
((f v) ss

There, similarly, monadic function f is applied first to basic value
v, and then the result applied to the pending state ss.


My question: What's the benefit of having the monadic function accept
only the basic value, deferring consideration of the state, as opposed
to having it accept both the basic value and the pending state together?

As I write this, I realize that following Clojure's definition ensures
that monadic functions return monadic values, and here a monadic value
is a function that accepts a state.

What's been difficult, though, is actually writing monadic functions for
use in the state monad. It feels wrong to define a function whose
outcome depends both on the input basic value and the input state, but
to have to cut the function in half, receiving the two values as
separate steps.

Sometimes the function depends only upon the input value, in which case
the `m-result' is sufficient to provide the resulting monadic
value. Sometimes the function depends on both the input value and the
state, in which case we have to just close over the input value and
defer its consideration until we receive the state later.

What would be lost by defining Clojure bind operator like this:

  (fn m-bind-state [mv f]
(fn [s]
  (let [[v ss] (mv s)]
(f v ss

Is there more to it than, Monadic functions must return monadic
values?

Any clarifying advice would be welcome.


Footnotes: 
¹ http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf
² http://www.haskell.org/all_about_monads/html/statemonad.html

-- 
Steven E. Harris

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


Re: Why do functions in the state monad only accept one value?

2010-03-16 Thread Steven E. Harris
Jarkko Oranen chous...@gmail.com writes:

[...]

 This way, you can write a function that works under many different
 monads, as long as it uses the generic facilities to return monadic
 values. eg. a lifted inc:

 (defn m-inc [v]
   (m-result (inc v))

 which can be used in the state monad as an argument to bind, even
 though it doesn't care about the state at all.

Ah, I hadn't realized that such functions -- of which I've now written
several for use in the state monad -- actually say nothing about the
state, and can be used in other monads as well.

That was helpful to consider.

-- 
Steven E. Harris

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


Re: Why do functions in the state monad only accept one value?

2010-03-16 Thread Steven E. Harris
Michał Marczyk michal.marc...@gmail.com writes:

 a State-using programme builds up a stateful computation first, then
 uses runState (or perhaps execState / evalState) to run it as a whole;
 only at this final step does the initial state actually get poured
 into the opening of the monadic pipe, as it were.

That's a good metaphor.

[...]

 You can use it multiple times, each time injecting a different initial
 value of state.

Ah, but here's where part of my confusion arises. With this treatment of
such a built-up computation, it's a kind of a zero-argument function, in
that there's no way to pass in a basic value to kick it off. Where
does the first basic value to be fed into the first monadic function
come from? Presumably it comes from the first monadic value in the
pipe. In your description above, it sounds like this first monadic
value must be committed to when buld[ing] up a stateful computation
first.

In the parser examples I've seen, the state provides the input
value. It's hard to find examples of other kinds of computations using
the state monad, but even something like do these arithmetic steps to
some input number, and count the number of operations in the state
would want to start off with some number as input, distinct from the
state, which would presumably start off with a count of zero. That
sounds like we'd have to build up the arithmetic steps as a monadic
function, not a monadic value, which we'd bind to (m-result
initial-value) to kick it off.

[...]

 BTW, if you feel you'd rather write something like (defn put [v s] [v
 v]) than a two-tier function like c.c.monads/set-state, you're free
 to do so; then you can use #(partial put %) for set-state.

Interesting idea.

 PS. Sorry if this is a bit chaotic...

I like the challenge of following your mental process. More examples
on this topic would be welcome.

-- 
Steven E. Harris

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


Re: Writing a put-if-absent operation a la Java's ConcurrentMap

2010-03-05 Thread Steven E. Harris
Stuart Halloway stuart.hallo...@gmail.com writes:

 It is mort important to focus on the semantics (commutative or last-
 one-wins) than the implementation details.

That's a tough pill to swallow. I understand the benefits of specifying
behavior to allow flexibility in an implementation, but here I think the
behavior is still underspecified. Or maybe it's just hasn't been
described well with enough comparative examples to allow it to sink
in. It feels like some of our discussion is still operating on
superstition.

 If you care about ordering, stick to alter. If you aren't sure, stick
 to alter.

Got it.

 I find a counter to be a useful example. If the purpose of the counter
 is to keep a total count of something that happened, then you can use
 commute.

This is true because even if commute runs once and increments the
counter, but then runs into a conflict, the commute operation will be
run again on a fresher value until it finally succeeds in committing
without conflict. This is similar to a manually-written atomic increment
operation using CAS in a spinning loop:

  for (int cur = val.get();
   !val.compareAndSet(cur, cur + 1);
   cur = val.get())
;

Or:

  int cur;
  do
  {
cur = val.get()
  }
  while (!val.compareAndSet(cur, cur + 1));

 But if the counter is used as an id generator within the transaction,
 then order matters and you have to use alter.

The key there is within the transaction, because if you used commute,
the commuted operation could be repeated upon conflict at the end of the
transaction and wind up succeeding, albeit with a different resulting
value than the one observed within the transaction, right?

-- 
Steven E. Harris

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


Re: Using deftype to define mutually recursive data inside agent

2010-03-04 Thread Steven E. Harris
ataggart alex.tagg...@gmail.com writes:

 You can use *agent* from inside an agent thread to obtain the
 current agent.

Is this documented?

-- 
Steven E. Harris

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


Re: Writing a put-if-absent operation a la Java's ConcurrentMap

2010-03-02 Thread Steven E. Harris
Meikel Brandmeyer m...@kotka.de writes:

 So using alter is the absolutely correct and nothing bad will
 happen. However you might construct superfluous default nodes in case
 the action is retried.  They are not assoc'd to the map, though.

Understood. Thanks for the explanation.

 The anonymous function is not necessary.

I missed this note in the documentation, despite having run my eyes over
it several times:

,
| Sets the in-transaction-value of ref to:
| 
| (apply fun in-transaction-value-of-ref args)
`

 What leads you to the idea it would be different?

Only the lack of confirming documentation walking through the behavior
under conflict.

 I think this is the whole point about STM, that you don't have to
 worry about such things.

Yes, but then writing with concurrency in mind is all about imagining
the odd things that will almost never happen, but you need to design in
anticipation of.

The STM presents some magic that's supposed to alleviate the
programmer of some worry, but without being clear about the scope of
that magic and the problems it alleviates, I don't know which problems
to ignore.

 There is (get the-map id (default-node)), but this does not assoc the
 value to the map. I assume your (default-node) is a little more
 complicated - and in particular non-constant.

Yes, you assume correctly. I thought through whether I could work with
the get-with-default operation, but concluded that I need the semantics
of the Java functions I had written as examples.

 I think the let above solves this problem, no?

Yes, I think it does. I'll either return a value that some prior thread
inserted in the map or the value that I just inserted. I take it that
`dosync' doesn't return any value until all of its changes can be
committed without conflict, such that the returned value with follow
from a successful commit against what was a consistent view of the refs
involved.

 In contrast to alter, commute would in case of conflict just go on and
 assoc the id again.

When you say assoc the id again, do you mean that in the example time
line above, B's alteration of the map would succeed, even though A's
alteration had succeeded just prior, without B retrying?

If so, there's more to be explained about `commute'. I'm imagining the
commit-time rules saying that if competing changes to the refs touched
by `commute' can be ignored, because the changes can be applied in
either order. But if the operation was something like `inc', two
competing threads would both commit a value one greater than when both
transactions started, which would result in a final value only one
greater, rather than two, as intended.

Reading the documentation again, I think these characterizations are
wrong. It sounds like `commute' runs /again/ at the commit point of the
transaction, but the whole transaction doesn't have to run again. It's
not clear whether `commute' /always/ invokes the provided function twice,
or only in the case of having detected a conflict against the target ref
at the would-be commit point.

 I think alter is exactly the right tool.

Good. I can understand `alter'. I'd still like to understand more about
`commute'.

I appreciate the discussion.

-- 
Steven E. Harris

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


Writing a put-if-absent operation a la Java's ConcurrentMap

2010-03-01 Thread Steven E. Harris
My application involves a graph with a node set, represented as map from
integral node ID to a node structure. Several threads need to look up
these node structures. This graph is constructed lazily, by which I mean
that the structures representing the nodes are only instantiated upon
first visiting of a given node. The per-node structures are like a color
map used to guide depth-first-traversal.

If I were building this map in Java, I could write an operation like
this using ConcurrentMap¹:

  Node ensureNodeExists(Id id, ConcurrentMapId, Node map)
  {
final Node defaultNode = createDefault();
final Node prev = map.putIfAbsent(id, defaultNode);
return null == prev ? defaultNode : prev;
  }

If there was no previous entry for the given ID, insert a default node
structure and return it. Otherwise, return the current node.

Given that nodes will never be deleted from the map, we could optimize
this function a little:

  Node ensureNodeExists(Id id, ConcurrentMapId, Node map)
  {
final Node current = map.get(id);
if (null != current)
  return current;

final Node defaultNode = createDefault();
final Node prev = map.putIfAbsent(id, defaultNode);
return null == prev ? defaultNode : prev;
  }

That involves an extra lookup in the case that the entry isn't currently
in the map, but saves construction of the default node for cases where
the entry is already in the map.


Suppose we want to write an analogous operation in Clojure. I think the
solution involves `dosync' and either `alter' or `commute', but I'm
having trouble reasoning about the semantics of those operations in the
face of collisions among competing threads.

My first attempt:

  (dosync
(or (*id-node-map* id)
(alter *id-node-map*
   #(assoc % id (create-default)

Ignoring the defect that each branch of the `or' form returns a
different kind of value (in one case, the mapped value, in the other
case, the map itself), I wondered whether it's possible that in between
when I first lookup the value and find it missing and when `alter' runs
that another thread could have jammed a value in there. Feeling
paranoid, next I wrote this:

  (dosync
(or (*id-node-map* id)
(alter *id-node-map* 
   #(update-in % [id]
   (fn [cur] (if (nil? cur)
   (create-default)
   cur))

In that case, if the value is already in the map, it looks like we still
wind up changing the *id-node-map* ref even if the map didn't need to
change.

Several questions arise:

o What happens if two threads run this operation concurrently? Will one
  fail and retry, backing off for finding the value now present in the
  map?

o Is there some map updating operation better suited to my goal here?
  The lookup ahead of time seems like it might not be necessary.

o Is there some way to capture the new value associated with the key
  without looking it up again /outside/ and /after/ the `dosync' form?
  The contract is that there's either no value associated with the key
  or there is a value, and once there's a value it will not change to be
  a different value. (These values are themselves agents.) But it's hard
  to tell from within `dosync' whether a proposed update to the map will
  be the one than wins.

o Assuming that `alter' is germane to the solution, how would `commute'
  behave differently? I understand that `commute' doesn't block writers
  and hence can retry. In my case, retrying after losing in the
  collision should result in finding that the competing thread already
  bound a value to the given key in the map.


It's been very difficult to find a thorough discussion of how `dosync',
`alter', and `commute' behave. In particular, if a transaction touches
several values with several `alter' or `commute' calls, and any one of
those values wind up conflicting with a competing transaction, does the
whole transaction fail and restart? Again, how do `alter' and `commute'
differ in such a case?


Footnotes: 
¹ http://java.sun.com/javase/7/docs/api/java/util/concurrent/ConcurrentMap.html

-- 
Steven E. Harris

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


Re: Question about how to write efficient code in functional style

2010-02-28 Thread e
Someone will have an elegant solution, but what comes to my mind is a
(somewhat) brute force loop-recur ... not not that much different from
what you suggested.  It would pass the under construction return lists to
itself and a dwindling amount (rest) of the original list.  Add first
from the dwindling source list to the appropriate return list on each pass.
When the source/input list is empty, return the constructed lists.

Only one pass through the input list.  The loop-recur pattern looks like it
makes recursive function calls, but it's just iteration.

On Sat, Feb 27, 2010 at 8:54 PM, logan duskli...@gmail.com wrote:

 Let's say I want to write a function that takes as an argument a list
 of n numbers, and returns 4 lists, a list of odd numbers that are
 multiples of 5, a list of even numbers that are multiples of 5, a list
 of odd numbers that are not multiples of 5, and a list of even numbers
 that are not multiples of 5.

 If I were writing this function procedurally, I could create 4 empty
 lists, and iterate through my input list once, using a compound if
 statement to add to the appropriate list.

 In functional style, I could use filter, but I can't seem to think of
 a solution that doesn't end up iterating through the whole list
 multiple times.

 Can someone please teach me what is the correct clojure approach?
 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.comclojure%2bunsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en

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

Re: difference between if/when

2010-02-28 Thread Steven E. Harris
Richard Newman holyg...@gmail.com writes:

 There are more subtle clues that you'll pick up in certain people's
 styles, too -- I'm sure my use of when has a very different pattern to
 a Java guy's, colored by my Common Lisp experience.

I'm still undecided whether to shake this habit:

,
| (defmacro unless [pred  body]
|   `(when-not ~pred ~...@body))
`

-- 
Steven E. Harris

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


Re: difference between if/when

2010-02-28 Thread Steven E. Harris
Richard Newman holyg...@gmail.com writes:

 Incidentally, I initially didn't know about `when-not` -- I figured
 that `unless` had simply been omitted -- so I defined:

 (defmacro unless [pred  body]
   `(when (not ~pred) ~...@body))

I did the same, and then was frustrated enough to dig through the core
API documentation. Finding `when-not' was nice, but the name still
doesn't work for me. Per your/our macro above, it's not really different
enough from `when' and `not' to warrant another name.

-- 
Steven E. Harris

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


Re: My first use of cells: hashing

2010-02-27 Thread Steven E. Harris
pthatcher pthatc...@gmail.com writes:

 I coded it up, and I liked the result and thought others might be
 interested.

There are several facilities used in your example that I'd like to look
into further. I found the `extend-class' function in the core library,
but where are the cell-related functions defined?

There's the dataflow library in Clojure contrib¹, but it doesn't have
an `update-cell' function or form `'. Where are you finding these? Is
there public documentation available?


Footnotes: 
¹ http://richhickey.github.com/clojure-contrib/dataflow-api.html

-- 
Steven E. Harris

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


Re: Code Review: how can I make this socket code more functional?

2010-02-16 Thread e
i'm interested in seeing how this progresses ... like how you'd spawn
handlers asynchronously to service the requests.  was thinking about doing
this exercise myself at some point.

On Tue, Feb 16, 2010 at 4:30 PM, Alan Dipert alan.dip...@gmail.com wrote:

 Hi Matt,
 I think what you're looking for is line-seq:

 http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/line-seq

 In your code, if you pass *in* to line-seq, you'll get back a seq of lines
 (the request headers).  Incidentally, I first ran into line-seq in the
 course of writing a Clojure web server as a first project.  You can see
 line-seq in action on line 52 of this gist, inside the 'handle-request'
 function: http://gist.github.com/203329

 I'm pretty new to Clojure myself so there might be a better way.  Hope
 this helps,

 Alan

 Excerpts from Matt Culbreth's message of 2010-02-16 16:17:57 -0500:
  Hello Group,
 
  I'm writing a web server in Clojure and I'd love to have a bit of help
  on a function I have.
 
  This function (and at http://gist.github.com/305909) is used to read
  the HTTP request from a client and to then act on it:
 
  (defn handle-request
  [in out]
  (binding [*in* (BufferedReader. (InputStreamReader. in))]
  (let [client-out (OutputStreamWriter. out)]
  (loop [lines []]
  (let [input (read-line)]
  (if
  (= (.length input) 0)
  ;; 0 length line means it's time to serve the
  resource
  (println lines)
  ;; add to the lines vector and keep going
  ;; note it makes the incoming request reversed
  (recur (cons input lines
 
  The code works fine; I've left out the bit that actually does
  something and replaced it with a println call.  It's not very
  functional feeling though.  The loop/recur and the building of a list
  seems very imperative to me.  I'd much rather use something from
  clojure.contrib.io, probably using read-lines or something.
 
  Thanks for looking and for any suggestions!
 
  Matt
 
 --
 Alan Dipert
 http://alan.dipert.org

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


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

Re: Emacs/Slime -- Slime wont eval but *inferior-lisp* will (Help a newbie out)

2010-02-15 Thread Steven E. Harris
joseph hirn joseph.h...@gmail.com writes:

 All seems to be well when I M-x slime, but if I enter (+ 1 2) it just
 hangs. If I switch to the *inferior-lisp* buffer and type this
 expression it returns 3 as expected.

I have the same problem, as documented here:

  http://thread.gmane.org/gmane.comp.java.clojure.user/24894/focus=24956


In the *inferior-lisp* buffer, try evaluating the following form:

  (.. java.lang.management.ManagementFactory (getRuntimeMXBean) (getName))

Does that cause SLIME's REPL to finally connect to Swank?

-- 
Steven E. Harris

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


Re: processing two collections

2010-02-14 Thread Steven E. Harris
Glen Rubin rubing...@gmail.com writes:

 How do I take an element from one collection and test for no remainder
 (e.g. (zero? (mod x y)), when dividing by every element of the second
 collection, before processing the next item in the first collection?

This form checks if every element of the second range is a factor of
every element in the first range:

,
| (let [r2 (range 100 150)]
|   (every?
| #(every? (partial (comp zero? mod) %) r2)
| (range 1000 2000)))
`

Note that the walk over (range 1000 2000) is the outer one, and the walk
over (range 100 150) (r2) is the inner one.

-- 
Steven E. Harris

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


Re: Clojure Dev Environment

2010-02-13 Thread Steven E. Harris
Wilson MacGyver wmacgy...@gmail.com writes:

 With the latest intelliJ 9.0.1, la clojure now just works.

On /one/ of my computers running Windows XP, I find that the REPL
doesn't start properly. Tracing IDEA and Java through Process Monitor,
it looks as though Java's attempt to open clojure.jar fails when loaded
for the REPL, and hence it can't find the required class (clojure.main),
even though IDEA can load the same Jar file for other reasons.

It's strange and frustrating.

-- 
Steven E. Harris

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


Re: Request for Feedback: Improve VimClojure's documentation

2010-02-11 Thread e
i can echo that last reply.  I wanted to use clojure and may return to it
... awesome idea.  But haven't had ANY luck with dev environments ... VC,
included.  gone down many blind alleys.  It was almost a year ago that I
tried, though.  perhaps I should try again.

On Thu, Feb 11, 2010 at 12:44 PM, Drew Vogel drewpvo...@gmail.com wrote:

 The result is horrible error messages like the one in the attached
 screenshot. I don't have a solution to contribute because I've never
 consistently solved these problems. Good luck with this effort. I'd like to
 see VC become more accessible.


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

Re: Inheriting from IDeref - good idea or bad practise?

2010-02-08 Thread Steven E. Harris
James Reeves weavejes...@googlemail.com writes:

 Would those more knowledgable about Clojure care to weigh in on
 whether it be a good idea to create a custom class inheriting from
 IDeref?

That's how promise is implemented, but that's supposed to be an internal
detail.

-- 
Steven E. Harris

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


Re: Clojure for system administration

2010-02-05 Thread e
On Fri, Feb 5, 2010 at 12:56 AM, Greg g...@kinostudios.com wrote:

 A much easier solution is to go with a lisp designed for exactly the task
 of scripting.


Woah!  Seems like an understatement.  This newLISP looks POWERFUL.  Lot's of
new stuff to read.  Thank you, thank you.


 I whole-heartedly recommend newLISP for this:

 http://www.newlisp.org/

 Clojure is excellent when you need a powerhouse LISP capable of great
 feats, but newLISP is far better suited for scripting tasks, it was designed
 for that.

 Or you can implement a *nix shell in Clojure. :-p

 - Greg

 On Feb 5, 2010, at 12:42 AM, Tim Clemons wrote:

  Perhaps the solution is to have a *nix shell implemented in Clojure.
  That would limit the start-up issue to a single initial instance.
  Then the user can proceed to use regular command-line functionality
  interspersed with Clojure scripts.  Think of it as a hybrid REPL.
 
  On Feb 4, 9:35 am, Phil Hagelberg p...@hagelb.org wrote:
  On Thu, Feb 4, 2010 at 8:33 AM, Stuart Sierra
 
  the.stuart.sie...@gmail.com wrote:
  Clojure can certainly do these things; clojure-contrib contains many
  file and io-related utilities.  But remember that Clojure, like any
  Java program, takes more time to start up than scripting languages
  like Perl/Bash/Ruby/Python, so it may be less suitable for programs
  that you intend to run at the command-line.
 
  Also relevant is the fact that launching Clojure from the command-line
  is very inconvenient compared to scripting languages. If you want
  something simple you can just put on your path, you'll need to wrap it
  in a bash (or other language) script anyway to handle the classpath,
  etc. The combination of startup time and the need to roll your own
  bash script even for simple things has kept me from wanting to use
  Clojure as a perlish-replacement.
 
  -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.comclojure%2bunsubscr...@googlegroups.com
  For more options, visit this group at
  http://groups.google.com/group/clojure?hl=en

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


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

Re: Heap implementation in Clojure

2010-02-02 Thread e
i was messing around a while back with this:
http://code.google.com/p/jc-pheap/

the algorithms work, but it's probably in a between-state.  I wasn't sure
what the interface should look like exactly, and I was recently adding
support for duplicate keys (but I wasn't sure if I should have two
structures or one ... the latter being more of the multimap I'm describing).

Oh, and I was starting to work on decreaseKey(), too ... but the runtime is
still, likely amortized for that one.  I actually had an idea that I'm not
sure has ever been done before to make that operation even more baked.  Fun
stuff.

The project does not depend on clojure, but shows clojure code as an
example.  If I recall, it all works.  H, maybe I'll get back into
working on it and variations, tho.

On Tue, Dec 15, 2009 at 5:16 AM, ataggart alex.tagg...@gmail.com wrote:



 On Dec 15, 1:49 am, ataggart alex.tagg...@gmail.com wrote:
  On Dec 14, 5:48 am, Mark Tomko mjt0...@gmail.com wrote:
 
   I wrote this implementation of a heap (or priority queue) in pure
   Clojure:
 
  http://pastebin.com/m2ab1ad5a
 
   It's probably not of any quality sufficient to be make it to the
   contrib package, but it seems to work.  Any thoughts on how it might
   be improved?
 
   Thanks,
   Mark
 
  Ideally such a collection would be usable with existing functions,
  e.g. pop, peek.  To accomplish that you really need to implement
  against the expected java interfaces.
 
  I've been playing with the deftype/defprotocol stuff in the new
  branch, so I figured I'd try to apply that to this problem.  This is
  what I came up with:
 
  http://gist.github.com/256815

 To be clear, my implementation just uses a sorted list, not a true
 heap tree.

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


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

Re: Trouble implementing Dijkstra algorithm in Clojure

2010-02-02 Thread e
folks may be interested in this thing I was working on a while back for
Dijkstra and Branch and Bound problems: http://code.google.com/p/jc-pheap/.

... I know this was a while ago :)

On Tue, Dec 8, 2009 at 11:26 PM, David Brown cloj...@davidb.org wrote:

 On Tue, Dec 08, 2009 at 03:22:47PM -0800, ataggart wrote:

 I would be very surprised if getting the first element from a sorted-
 set wasn't ~O(1).

 As has been mentioned, it probably isn't if the set is a tree.

 But, also, usually, in addition to getting the first element, we also
 are going to want a set without the first element to represent the
 rest of the data.

 Both a sorted-set and a priority-queue are probably O(log n) for the
 first/rest operation, but the constant factor is likely to be quite
 different.

 David

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


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

Re: Promise/Deliver use cases

2010-01-30 Thread Steven E. Harris
Jeff Rose ros...@gmail.com writes:

Getting with a timeout versus without one is the difference of:

 ; blocking deref
 @p

 ; deref with 100ms timeout
 (.get (future @p) 100 TimeUnit/MILLISECONDS)

But the former just blocks on the promise being delivered, while the
latter creates an anonymous function, creates a proxy Future around it,
submits it for execution on a separate thread, and then blocks on the
function completing and (possibly) yielding a return value. That's much
more than a syntactic difference.

I tried to rewrite `promise' in terms of an AbstractQueuedSynchronizer
so that I could expose timed waits on it, but I got hung up with lack of
access to protected methods in the `proxy' macro.

-- 
Steven E. Harris

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


Re: Clojure Conference Poll

2010-01-26 Thread e
I didn't know this was a vote for location. If it is, DC would work for me.
I thought it was more about weekend vs week.  I'd agree weekend is better.

On Tue, Jan 26, 2010 at 4:09 PM, Joseph Smith j...@uwcreations.com wrote:

 +1 Lincoln/Omaha Nebraska.   :)

 ---
 Joseph Smith
 j...@uwcreations.com
 (402)601-5443



 On Jan 26, 2010, at 2:29 PM, Michel Vollebregt klmn...@gmail.com wrote:

  +1 for Europe

 On Jan 26, 12:22 am, mudphone kyle...@gmail.com wrote:

 +1 Paris

 On Jan 22, 11:54 pm, Konrad Hinsen konrad.hin...@fastmail.net wrote:
 On 22 Jan 2010, at 22:15, Wilson MacGyver wrote:

  I vote let's turn this into a clojure vacation, and hold it in an
 exotic location.


  Otherwise, hey, Columbus Ohio is as good as any other city. :)


  My vote is for Paris, France :-)


  Konrad.


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


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


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

Re: newbie question about ns and :require

2010-01-26 Thread Steven E. Harris
Raoul Duke rao...@gmail.com writes:

 so, like, this means i /not/ the only one who finds the whole
 (whatever you want to call it) include/import syntax kinda crazy?

I was expecting even more of a backlash from those who already get
it.

For now, I only understand it as, There are a lot of options and
whichever one you think sounds appropriate is probably the wrong
choice. Be prepared to try several times.

-- 
Steven E. Harris

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


Re: newbie question about ns and :require

2010-01-25 Thread Steven E. Harris
Justin Kramer jkkra...@gmail.com writes:

 You may find this ns cheatsheet helpful:

 http://gist.github.com/284277

That is most helpful.

What's not helpful is the weird mix of lists and vectors used by these
forms. When I finally made it to :rename accepting a map, I had to take
a break.

-- 
Steven E. Harris

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


Re: Debugging in Clojure

2010-01-24 Thread e
It has confused me since the day I tried to mess around with clojure that
this topic isn't brought up more (not that I follow clj regularly) ... so
I'm happy to learn that someone added trace capabilities.

That said (and I'm not trying to make this a charged statement ... just a
way to learn more) I had always thought that one of the key things that made
lisp so complete was that programs don't just crash ... that debugging is
fully-baked into the *core* of everything.  Now, I don't remember much about
the debugging capabilities of, say, CL, but my understanding is that *after*
a crash, you can interrogate the state of objects. . . .rather than having
to preemptively guess at what you may want to know in the future.

Trace is better than logging.  Logging just seems like a flawed approach (as
others have pointed out).  I mean, Log4j (or related) is desired in Java so
that someone can get more information without a recompile.  But in a
dynamically run language or in an environment where you aren't just the user
of some closed-off code, you may as well just put print statements where you
need them.  The latter is what I was advised to do in Clojure, and it was a
real turn-off for me.  Maybe the lack of appeal comes from having to squeeze
in that extra do nesting -- or maybe because you then have to go through
and remove all that stuff later.  Or in the case of logging? you always
leave it there, FOREVER.  Even if you never end up caring about some state
in a production environment!!!

So, anyway, it seems to me that folks have been successfully chipping away,
borrowing, and improving the cool things about CL for years, but, amazingly,
a newb to Lisp like me can still find something unique about CL.  Or, at
least it seems unique to me  this concept of leaving the user suspended
in the middle of the execution exactly where it crashes without having to
know before-hand that they should have somehow debugged.  It's the only
language I know of that comes that close to giving you the true state of a
program when it crashed.  I mean, any time you have to rerun a program,
you have to say, I hope I can repeat (or remember) the conditions.

But maybe there are things I'm not considering.  It seems like an FP-lang
ought to be able to handle something like that environment easily.  On the
other hand, a parallel world could have real troubles bothering to trying to
figure out what any of that would mean.

I wonder how CL users feel about this issue.  Is it a feature they really
love or something they wouldn't miss because they never really took
advantage of it?



On Sun, Jan 24, 2010 at 8:22 AM, Gabi bugspy...@gmail.com wrote:

 Be careful of deftrace. It has a bug that crashes when the defn'ed
 funcs have string comment on the top of the func

 On Jan 23, 7:02 am, ataggart alex.tagg...@gmail.com wrote:
  On Jan 22, 6:27 pm, Mike Meyer mwm-keyword-googlegroups.
 
 
 
  620...@mired.org wrote:
   On Fri, 22 Jan 2010 17:25:39 -0800
 
   ajay gopalakrishnan ajgop...@gmail.com wrote:
I dont mind using println. The problem is that needs to be inside a
 do or
when ... and that is not really part of my code. When the time comes
 to
remove the prints, i need to remove all these do blocks too. I can
 leave
them as it is I guess, but then it is not neat and non-idiomatic.
 From all
the replies, it seems that Debugging is going to be a pain in the
 Lisp style
languages. How do people in Lisp/Scheme debug it?
 
   In the REPL. That's a pretty complete debugger, all by itself. In
   something like SLIME, you get the ability to examine the call stack,
   etc. while things are running.
 
   The trace package just dumps arguments/results of functions while they
   run. It's a primitive tool, but better than println's in many cases:
 
   user it, then use dotrace:
 
   user (use 'clojure.contrib.trace)
   nil
   user (defn foo [coll] (reduce + coll))
   #'user/foo
   user (defn bar [coll] (map inc coll))
   #'user/bar
   user (dotrace [foo bar] (foo (bar [1 1 1])))
   TRACE t7043: (bar [1 1 1])
   TRACE t7043: = (2 2 2)
   TRACE t7044: (foo (2 2 2))
   TRACE t7044: = 6
   6
   user (dotrace [foo +] (foo (bar [1 1 1])))
   TRACE t7071: (foo (2 2 2))
   TRACE t7072: |(+ 2 2)
   TRACE t7072: |= 4
   TRACE t7073: |(+ 4 2)
   TRACE t7073: |= 6
   TRACE t7071: = 6
   6
 
   and so on.
 
   mike
   --
   Mike Meyer m...@mired.org
 http://www.mired.org/consulting.html
   Independent Network/Unix/Perforce consultant, email for more
 information.
 
   O ascii ribbon campaign - stop html mail -www.asciiribbon.org
 
  See, I *knew* there had to be a way to do it!  Clearly I wasn't
  grokking the docs for dotrace.  If the authors of of c.c.trace are
  amenable, I'm inclined to add this functionality to a variant of the
  c.c.logging/spy macro, something like:
 
  (spy [foo bar] (foo (bar [1 1 1])))

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To 

Re: Debugging in Clojure

2010-01-24 Thread e
interesting.  thanks for the thoughtful reply.

On Sun, Jan 24, 2010 at 2:08 PM, Richard Newman holyg...@gmail.com wrote:

 That said (and I'm not trying to make this a charged statement ... just a
 way to learn more) I had always thought that one of the key things that made
 lisp so complete was that programs don't just crash ... that debugging is
 fully-baked into the *core* of everything.  Now, I don't remember much about
 the debugging capabilities of, say, CL, but my understanding is that *after*
 a crash, you can interrogate the state of objects. . . .rather than having
 to preemptively guess at what you may want to know in the future.


 This is  largely down to CL's condition system: problems are usually
 reported as conditions, which stop execution without unwinding the stack.
 Unlike exceptions, you typically get a REPL in the environment of the
 condition (so you can view locals, inspect objects, etc.) — a bit like being
 dropped into the debugger in an IDE. Unlike an IDE, you can *do things* to
 the running program, and the condition often offers restarts (e.g., a
 compile failed condition might offer to retry the compilation). That means
 you can fix and continue, or just find out what went wrong.

 These make an unexpected condition into an interactive process, rather than
 merely an opportunity for logging. By the time you were ready to ship your
 app, you'd experienced most of the failures, and introduced static or
 dynamic handling for those problems.

 Unfortunately, Java can't match CL's condition system. There are steps
 towards including some of its power in Clojure (see errorkit).

 That said, I still use tracing extensively in Common Lisp development:
 things might not crash, but I still need to see what's going on to identify
 the root cause of some high-level behavior. I also use print statements:
 often trace output is too verbose, or I need to see the result of some
 computation on an intermediate value. Sometimes there's no condition to
 raise.


  Trace is better than logging.  Logging just seems like a flawed approach
 (as others have pointed out).  I mean, Log4j (or related) is desired in Java
 so that someone can get more information without a recompile.  But in a
 dynamically run language or in an environment where you aren't just the user
 of some closed-off code, you may as well just put print statements where you
 need them.  The latter is what I was advised to do in Clojure, and it was a
 real turn-off for me.  Maybe the lack of appeal comes from having to squeeze
 in that extra do nesting -- or maybe because you then have to go through
 and remove all that stuff later.  Or in the case of logging? you always
 leave it there, FOREVER.  Even if you never end up caring about some state
 in a production environment!!!


 I disagree that logging is a flawed approach. Tracing is an interactive
 tool. Logging allows you to see what happened before you were watching
 (which is important in the case of systems that are running for months or
 years, on many different machines, handling millions of requests). It also
 helps to produce a usable record of events in your program, which aren't
 always visible in trace output — e.g., this request was invalid because
 this header appears to be truncated. Try spotting that in trace 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.comclojure%2bunsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en


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

Proxy macro, and calling on a protected method

2010-01-24 Thread Steven E. Harris
The documentation for the `proxy' macro mentions lack of access in the
defined implementation to protected members:

,[ proxy ]
| Note that while method fns can be provided to override protected
| methods, they have no other access to protected members, nor to super,
| as these capabilities cannot be proxied.
`
 
I just tried to define a proxy that overrides a protected method in the
base class, and within that overridden method body attempts to call on
some other protected method. It fails, reporting

,[ IllegalArgumentException message prefix ]
| No matching field found
`

That confirms the warning in the documentation.

Is there any other way within Clojure to define a class that does have
access to the protected methods of its base class? My motivating
example: Writing an AbstractQueuedSynchronizer implementation, which
involves a lot of interplay among overridden protected methods and
calling on protected methods.

-- 
Steven E. Harris

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


Re: Proxy macro, and calling on a protected method

2010-01-24 Thread Steven E. Harris
.Bill Smith william.m.sm...@gmail.com writes:

 you can use java.lang.reflect.Method.setAccessible to make an
 otherwise protected method available for public access.

It looks like one would have to hang on to the Method object and reuse
it, as setting one Method instance's accessibility has no influence over
/other/ instances of the same Method. Changing the accessibility doesn't
seem to have global effect throughout the program.

-- 
Steven E. Harris

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


Re: Promise/Deliver use cases

2010-01-23 Thread Steven E. Harris
Jeff Rose ros...@gmail.com writes:

 The future is used because they have a timeout feature when using the
 .get method.

Should there be a corresponding timeout-based `deref' function¹
(deref-within?) for promises? Having to close a function over your
@p form and spawn a job on a separate thread seems like way too much
work just to get a timeout-based wait on the promise's delivery
arriving.


Footnotes: 
¹ http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/deref

-- 
Steven E. Harris

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


Re: Promise/Deliver use cases

2010-01-22 Thread Steven E. Harris
Baishampayan Ghose b.gh...@ocricket.com writes:

 It would be great if someone pointed out some example usage of
 promise/deliver.

I've used them in cases where I think I need a future, but I don't want
to wrap the future around some function just to catch and propagate its
result elsewhere. In Clojure, the `future' and `future' call functions
include the spawning of the function's execution in another
thread. That's really several separate concerns:

  future = function + promise + async + deliver

Exposing `promise' and `deliver' directly allows one to use other means
of spawning asynchronous work (or not) while still retaining the
block-on-a-latching-result capability.

-- 
Steven E. Harris

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


Re: Suggest slime-redirect-inferior-output be default for Swank clojure

2010-01-22 Thread Steven E. Harris
Alex Stoddard alexander.stodd...@gmail.com writes:

 With that all stdout ends up in the repl buffer.

I spent hours last weekend working on a rebind-in-other-threads
solution, completely forgetting that one can adjust SLIME to handle this
problem.

Also frustrating: Why don't any of the printing functions accept a
Writer or OutputStream as a substitute for *out*? Common Lisp has a nice
treatment of these kinds of functions¹: the output stream argument is
optional, and, if specified, accepts nil and t as special stream
designators² as well.


Footnotes: 
¹ http://www.lispworks.com/documentation/HyperSpec/Body/f_wr_pr.htm
  http://www.lispworks.com/documentation/HyperSpec/Body/f_format.htm
² 
http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_s.htm#stream_designator

-- 
Steven E. Harris

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


Re: Lift and bind

2010-01-12 Thread Steven E. Harris
jim jim.d...@gmail.com writes:

 You know, I think you're right. I would refer you to part 2 of
 Konrad's monad tutorial, but the link is broken. Check google's cache,
 if you want to read an explanation immediately.

That's how I've been reading his tutorials, as WordPress isn't
delivering the pages.

In A monad tutorial for Clojure programmers (part 2), he writes:

,
| Perhaps the most frequently used generic monad function is m-lift. It
| converts a function of n standard value arguments into a function of n
| monadic expressions that returns a monadic expression.
`

I take it monadic expression is a synonym for monadic value.

 I'll have to go change that. Thanks for pointing it out and sorry for
 any confusion.

Well, having caught a conflict, it caused me to look deeper several
times until I felt confident enough to ask. Learning was my goal, and
your essays have been tremendously helpful.

-- 
Steven E. Harris

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

Lift and bind (was: Understanding the continuation monad's bind operator)

2010-01-11 Thread Steven E. Harris
Konrad Hinsen konrad.hin...@fastmail.net writes:

 For a function of a single argument, m-lift and m-fmap are equivalent.

In Jim Duey's essay Higher Level Monads¹, he writes the following on the
lift operator:

,[ m-lift ]
| If you have a function that you would like to turn into a monadic
| function, that is a function that can be passed to m-bind, you use
| m-lift.
| 
| m-lift takes two parameters, a function to lift and the number of
| arguments that function accepts. The argument count is the first
| parameter and the function is second. The return value is a function
| that can be passed to m-bind.
`

Isn't it the case, though, that a lifted function /can't/ be passed to
bind, because it's not a monadic function? A lifted function takes
monadic values as input, rather than a basic value.

Is there some operator that converts a normal function

  a - b

to a monadic function

  a - m b

such that one could adapt a normal function for use in and among some
other monadic functions (such as with m-chain)? I'm not sure such a
translation is possible for all monads.

I considered something like this

,
| (defn as-monadic-fn [f]
|   (fn [v]
| (m-result (f v
`

but it looks too simple.


Footnotes: 
¹ http://intensivesystems.net/tutorials/monads_201.html

-- 
Steven E. Harris

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

Re: SLIME/Swank problem with swank.util.sys/get-pid and RuntimeMXBean

2010-01-09 Thread Steven E. Harris
Phil Hagelberg p...@hagelb.org writes:

 There was some discussion about it a couple months ago:

I picked up the torch today, in hope that others will try again for a
better resolution:

  http://thread.gmane.org/gmane.lisp.slime.devel/9178/focus=9383

-- 
Steven E. Harris

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

Re: SLIME/Swank problem with swank.util.sys/get-pid and RuntimeMXBean

2010-01-08 Thread Steven E. Harris
Phil Hagelberg p...@hagelb.org writes:

 If someone would volunteer to fix it, I'd be thrilled. Nobody who is
 interested in using CL and Clojure at the same time has stepped
 forward so far, which is why it's currently broken.

Can you characterize what needs to be fixed?

-- 
Steven E. Harris

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

Re: SLIME/Swank problem with swank.util.sys/get-pid and RuntimeMXBean

2010-01-07 Thread Steven E. Harris
Phil Hagelberg p...@hagelb.org writes:

 Could you try installing SLIME via ELPA as recommended in the
 swank-clojure readme?

That will be a project I'll have to defer until the weekend, as I've
never used ELPA. I use the CVS SLIME almost daily for Common Lisp work,
so I'm reluctant to give it up. Also, it's not a tenable situation to
fork SLIME for Clojure support.

 CVS head is known to have introduced incompatibilities with Clojure.

Is the git repository at git://git.boinkor.net/slime.git just tracking
the CVS repository, or is that the same as the ELPA-hosted one? I did
try all of this with the git version and found the exact same behavior
as with the CVS version.

-- 
Steven E. Harris

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

Re: Understanding the continuation monad's bind operator

2010-01-07 Thread Steven E. Harris
Thank you, Konrad. Your explanation was perfect.

-- 
Steven E. Harris

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

Re: Understanding the continuation monad's bind operator

2010-01-07 Thread Steven E. Harris
Konrad Hinsen konrad.hin...@fastmail.net writes:

 When the monadic values are functions representing computations,
 monadic composition yields a new function but doesn't execute
 anything. When the monadic values represent results of computations,
 then monadic composition implies execution of the computational steps.

Can you recommend a book that covers aspects of monads like these? I'd
like to learn more about the abstract concepts than their implementation
in a particular language.

-- 
Steven E. Harris

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

Re: Understanding the continuation monad's bind operator

2010-01-06 Thread Steven E. Harris
Konrad Hinsen konrad.hin...@fastmail.net writes:

 Exactly. The result of m-bind must be a continuation-accepting  
 function again.

Yes, and invoking 'mv' yields such a function.

 That's the role of the outer layer (fn [c] ...).

That one adds /another/ layer, but the inner function returned by 'mv'
has the same signature, right?

 It is indeed a value of the right type, but it is not right value that  
 represents the composite computation.

Ah, now we're getting somewhere.

 This version of m-bind would not return the composite computation, but  
 rather execute it immediately. This is best seen by the position of  
 mv. In your m-bind, mv is called when m-bind is called. That's not the  
 desired behaviour.

I'm interested in what you mean by composite computation, because I
think it's hinting at some concept for monads that I missed. If, as you
say, executing the function immediately is not acceptable behavior, then
I infer that the goal is to delay evaluation of the monadic function 'f'
until someone finally passes in a real continuation as, say, by the
`run-cont' function. Is that right?

If so, is it the case with all or most monads that the bind operator is
not meant to actually perform computation on the spot, but rather to
compose a delayed computation, or is this delaying particular to the
continuation monad?

-- 
Steven E. Harris

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

Re: Understanding the continuation monad's bind operator

2010-01-06 Thread Steven E. Harris
jim jim.d...@gmail.com writes:

 Don't know if you saw, but I did a whole tutorial on the continuation
 monad.

Your essay is how I got started with monads in Clojure. I've read it six
times now (along with five other of your essays on the subject), but
perhaps I missed the requirement pertaining to delaying evaluation of
the monadic function provided to bind.

-- 
Steven E. Harris

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

Re: Understanding the continuation monad's bind operator

2010-01-06 Thread Steven E. Harris
I have a few more questions concerning how one interacts with a
continuation monad. It's clear that a monadic function accepts some
base value and returns a monadic value, in turn being a function
accepting a single continuation argument.

That means that a monadic function has a signature like

  a - m b

Say that we're looking to use some normal functions with this
monad. Those functions may have signatures like

  a - b

They clearly don't return the right kind of value. There must be some
way to integrate such functions without writing new wrappers around them
by hand. Is this a job for `m-fmap'? Reading the implementation, it
looks like it would take a normal function and allow it to call on the
basic value extracted from a monadic value.

The lift operator also sounded relevant, but, if I understand it
correctly, it converts a normal function to one that accepts a monadic
value and returns a monadic value. That's the wrong argument type to be
used with bind -- which wants to call on a monadic function with a basic
value -- so I don't understand when one would want to use lift. When
would one be able to call on a lifted function? A simple example would
help.

-- 
Steven E. Harris

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

Understanding the continuation monad's bind operator

2010-01-04 Thread Steven E. Harris
In clojure.contrib.monads, there's a monad defined called cont-m to
model continuations. Its bind operator -- `m-bind` -- is defined as
follows:

,
| (fn m-bind-cont [mv f]
|   (fn [c]
| (mv (fn [v] ((f v) c)
`

I'm curious why there's an extra delaying wrapper function there. The
outermost `fn' form taking the argument c as a continuation looks like
it serves only to delay evaluation of the remaining forms.

The parameter mv is a monadic value which, for the continuation monad,
is a function accepting a single continuation argument. The parameter
f is a monadic function which, again, for the continuation monad, is a
function accepting a value offered by a continuation and returning a
monadic value -- another function accepting a single continuation
argument.

If all of that is true, then the form

,
| (f v)
`

should evaluate to a monadic value and be suitable as a return value
from `m-bind'. In short, why is this not an acceptable implementation?

,
| (fn m-bind-cont [mv f]
|   (mv (fn [v] (f v
`

-- 
Steven E. Harris

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


Re: SLIME/Swank problem with swank.util.sys/get-pid and RuntimeMXBean

2010-01-03 Thread Steven E. Harris
Rob Wolfe r...@smsnet.pl writes:

 Do you use slime-indentation.el in your configuration?

Yes. It turns out that I have another Lisp-related initialization file
that contained the following form:

,
| (slime-setup '(slime-fancy
|slime-asdf
|slime-fontifying-fu
|slime-indentation
|slime-indentation-fu
|slime-banner))
`

Removing the indentation-related entries fixed the `etypecase' Elisp
error. Unfortunately, the SLIME-Swank handshake still doesn't complete
(and hence the SLIME REPL doesn't start up) without the aforementioned
prodding.

-- 
Steven E. Harris

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


Re: SLIME/Swank problem with swank.util.sys/get-pid and RuntimeMXBean

2010-01-02 Thread Steven E. Harris
Phil Hagelberg p...@hagelb.org writes:

 But I'm not quite following on the exact problem and specific repro
 case; could you clarify?

Yes. When I start SLIME, the Swank back-end starts and presents the
Clojure REPL in the *inferior-lisp* buffer. Right after that, the SLIME
front-end sends an Emacs REX command to the Swank back-end, asking it
to invoke the `connection-info' function.

At this point, the SLIME front-end has reported that it's trying to
connect. The Swank back-end receives the REX request, invokes the
`connection-info' method on some thread separate from the thread
servicing the Clojure REPL, and hangs in its call to `get-pid'.

Because the Swank back-end thread servicing the call to
`connection-info' hasn't responded, the SLIME front-end is hung waiting
for its REX to complete to gather the `connection-info' result. Not
until the SLIME front-end has received that result will it finally
announce that it succeeded connecting and present the SLIME REPL.

It's not just the SLIME REPL that won't work until that
`connection-info' REX completes. Any buffers that attempt to submit
forms to Clojure for evaluation will not receive a result; the requests
are merely queued because the SLIME front-end has not completed its
connection and initial handshake.

The call to `get-pid' hangs on its call to

  RuntimeMXBean#getName()

which is part of the first path taken by `get-pid':

,
| (.. java.lang.management.ManagementFactory
| (getRuntimeMXBean)
| (getName)
| (split @))
`

Now, I found a way to unblock that hung call to RuntimeMXBean#getName():
In the Clojure REPL available in the *inferior-lisp* buffer, I can
evaluate the following form:

,
| (.. java.lang.management.ManagementFactory (getRuntimeMXBean) (getName)
`

That evaluation takes place in the thread servicing the Clojure REPL,
which is a different thread from the one blocked in the REX call to
`connection-info' and, transitively, `get-pid'.

The above form evaluates immediately in he Clojure REPL and, as a
side-effect I don't yet understand, /also/ causes the call blocked in
the Swank REX-servicing thread to complete as well. Hence, `get-pid'
completes, the `connection-info' completes, then the SLIME front-end
receives its reply and finally sets up the SLIME REPL. From then on, all
is well.

I've been searching the Web looking for similar complaints about such a
call hanging, and so far I've come up blank. Again, note that calling
ManagementFactory#getRuntimeMXBean() from the Clojure REPL is not
sufficient to unblock the other thread hung in `get-pid'; it takes
calling RuntimeMXBean#get() -- actually using the RuntimeMXBean
instance -- to unblock the other thread. Perhaps there's some lazy
initialization going on in Sun's RuntimeMXBean implementation.

 Does it occur with the latest version of swank-clojure?

Yes. I'm tracking the tip of the master branch via Git.

Here's the stack:

o swank-clojure
  Git head.

o SLIME
  Both CVS head and git://git.boinkor.net/slime.git head behave the same
  way, as the offending calls are in swank-clojure.

o Clojure 1.1.0
  Downloaded Jar from code.google.com.

o GNU Emacs 23.1.1

o Windows XP 32-bit

-- 
Steven E. Harris

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


Re: SLIME/Swank problem with swank.util.sys/get-pid and RuntimeMXBean

2010-01-02 Thread Steven E. Harris
Steven E. Harris s...@panix.com writes:

 it takes calling RuntimeMXBean#get() -- actually using the
 RuntimeMXBean instance -- to unblock the other thread.

I meant RuntimeMXBean#getName() there.
My typing is poor this morning.

-- 
Steven E. Harris

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


Re: SLIME/Swank problem with swank.util.sys/get-pid and RuntimeMXBean

2010-01-02 Thread Steven E. Harris
Steven E. Harris s...@panix.com writes:

 In the meantime, I'll continue the investigation.

Here are two thread dumps of the Java process running Clojure and Swank,
which, at this time, has a live Clojure REPL, but the Swank call to
`connection-info' hasn't completed yet.

This first one comes via jvisualvm:

==
2010-01-02 10:55:39
Full thread dump Java HotSpot(TM) Client VM (14.3-b01 mixed mode, sharing):

RMI TCP Connection(4)-192.168.1.35 daemon prio=6 tid=0x02e43000 nid=0x15f8 
runnable [0x0377f000]
   java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
- locked 0x23215700 (a java.io.BufferedInputStream)
at java.io.FilterInputStream.read(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown 
Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown 
Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown 
Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

   Locked ownable synchronizers:
- 0x2321c928 (a java.util.concurrent.locks.ReentrantLock$NonfairSync)

RMI TCP Connection(idle) daemon prio=6 tid=0x02f74c00 nid=0x121c waiting on 
condition [0x0372f000]
   java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for  0x231df420 (a 
java.util.concurrent.SynchronousQueue$TransferStack)
at java.util.concurrent.locks.LockSupport.parkNanos(Unknown Source)
at 
java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(Unknown Source)
at java.util.concurrent.SynchronousQueue$TransferStack.transfer(Unknown 
Source)
at java.util.concurrent.SynchronousQueue.poll(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

   Locked ownable synchronizers:
- None

JMX server connection timeout 22 daemon prio=6 tid=0x02f70400 nid=0x324 in 
Object.wait() [0x036df000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on 0x231e31d8 (a [I)
at 
com.sun.jmx.remote.internal.ServerCommunicatorAdmin$Timeout.run(Unknown Source)
- locked 0x231e31d8 (a [I)
at java.lang.Thread.run(Unknown Source)

   Locked ownable synchronizers:
- None

RMI Scheduler(0) daemon prio=6 tid=0x02b4e000 nid=0x1430 waiting on condition 
[0x0368f000]
   java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for  0x231b9ae0 (a 
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(Unknown Source)
at 
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(Unknown
 Source)
at java.util.concurrent.DelayQueue.take(Unknown Source)
at 
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown 
Source)
at 
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown 
Source)
at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

   Locked ownable synchronizers:
- None

RMI TCP Connection(idle) daemon prio=6 tid=0x02e4b400 nid=0x1608 waiting on 
condition [0x0363f000]
   java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for  0x231df420 (a 
java.util.concurrent.SynchronousQueue$TransferStack)
at java.util.concurrent.locks.LockSupport.parkNanos(Unknown Source)
at 
java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(Unknown Source)
at java.util.concurrent.SynchronousQueue$TransferStack.transfer(Unknown 
Source)
at java.util.concurrent.SynchronousQueue.poll(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

   Locked ownable synchronizers:
- None

RMI TCP Accept-0 daemon prio=6 tid=0x02b2e800 nid=0x128c runnable [0x035cf000]
   java.lang.Thread.State: RUNNABLE
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(Unknown Source)
- locked 0x231cf4e0

Re: SLIME/Swank problem with swank.util.sys/get-pid and RuntimeMXBean

2010-01-02 Thread Steven E. Harris
Steven E. Harris s...@panix.com writes:

 In the meantime, I'll continue the investigation.

And yet more information: Apparently it's not critical to call on the
RuntimeMXBean#getName() method specifically to kick the Swank thread out
of its blocking call; just about /any call on a Java method/ from the
Clojure REPL will unblock the Swank thread and make the connection
complete.

For example, I've tried calling

  java.util.concurrent.Executors#newSingleThreadExecutor()
  java.util.Collections#emptySet()
  java.lang.Math#max()

and both work to unblock the Swank thread, but this one does not:

  java.lang.Integer#parseInt()

Now get this: Right before the SLIME-Swank connection completes, Emacs
beeps and prints the following two lines in the *Messages* buffer:

,
| error in process filter: cond: etypecase failed: defun, (number cons string)
| error in process filter: etypecase failed: defun, (number cons string)
`

Those errors messages come from the ELisp evaluator. Strangely, I can't
find any etypecase or typecase form in file slime.el that tolerates all
three of those types (number, cons, and string), so it's hard to figure
out where the error is arising.

-- 
Steven E. Harris

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


Re: SLIME/Swank problem with swank.util.sys/get-pid and RuntimeMXBean

2010-01-02 Thread Steven E. Harris
Rich Hickey richhic...@gmail.com writes:

 Perhaps it would be best to paste such dumps somewhere, rather than
 mail to the entire list?

I'll do that next time. Sorry for the noise.

-- 
Steven E. Harris

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


Re: SLIME/Swank problem with swank.util.sys/get-pid and RuntimeMXBean

2010-01-02 Thread Steven E. Harris
Steven E. Harris s...@panix.com writes:

 Now get this: Right before the SLIME-Swank connection completes, Emacs
 beeps and prints the following two lines in the *Messages* buffer:

 ,
 | error in process filter: cond: etypecase failed: defun, (number cons string)
 | error in process filter: etypecase failed: defun, (number cons string)
 `

I caught the Emacs debugger trace here:

  http://paste.lisp.org/display/92936

It looks to be a problem parsing the indentation recommendations sent
from Swank.

-- 
Steven E. Harris

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


Re: Clojure/SLIME/Emacs questions

2010-01-01 Thread Steven E. Harris
Stefan Kamphausen ska2...@googlemail.com writes:

 you may want to read the thread
 http://groups.google.com/group/clojure/browse_frm/thread/3e5f416e3f2a1884/337057edae5dcdc3

I had read that thread /twice/ before, as well as the thread on the
SLIME mailing list, but I had neglected to try disabling
autodoc-mode. This morning, doing so makes things work much better.

However, I still notice that when I first run SLIME, the *inferior-lisp*
buffer comes up with a responsive REPL, but the SLIME REPL connection is
flaky. It takes a long time to finally come through, if it ever
does. Perhaps there's some race condition there.

Sometimes taking focus away from the Emacs window, doing something,
else, and returning to Emacs will cause the SLIME REPL to finally wake
up and finish its connection sequence. At that point the animated REPL
banner flies out and I have a working REPL.

But presentations still don't work.

-- 
Steven E. Harris

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


Re: Clojure/SLIME/Emacs questions

2010-01-01 Thread Steven E. Harris
Steven E. Harris s...@panix.com writes:

 This morning, doing so makes things work much better.

Still I see this in the *inferior-lisp* buffer when starting slime:

,
| (require 'swank.swank)
| 
| (swank.swank/ignore-protocol-version 2009-12-23)
| 
| (swank.swank/start-server c:/DOCUME~1/seh/LOCALS~1/Temp/slime.3420 
:encoding iso-latin-1-unix)
| 
| Listening for transport dt_socket at address: 
| Clojure 1.1.0
| user= 
| WARNING: reader macro ^ is deprecated; use meta instead
| WARNING: reader macro ^ is deprecated; use meta instead
| WARNING: reader macro ^ is deprecated; use meta instead
| WARNING: reader macro ^ is deprecated; use meta instead
| WARNING: reader macro ^ is deprecated; use meta instead
| WARNING: reader macro ^ is deprecated; use meta instead
| WARNING: reader macro ^ is deprecated; use meta instead
| WARNING: reader macro ^ is deprecated; use meta instead
| WARNING: reader macro ^ is deprecated; use meta instead
| nil
| user= user= 2009-12-23
| user= user= Connection opened on local port  3464
| #ServerSocket ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=3464]
| user= user= user= 
`

Note that I'm using Clojure 1.1.0. Could that be the problem?
This is within GNU Emacs 23.1.1 on Windows XP.

Once that *inferior-lisp* buffer is up, if I run `slime-repl', the REPL
may take an arbitrarily long time to finally connect to Swank. And if it
does ever connect, and I shut it down via the sayoonara command, I
can't get it to start again successfully.

-- 
Steven E. Harris

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


  1   2   3   >