Re: Sierra's Component

2024-04-06 Thread Paul Stadig
You can do either. If you pass the config as a dependency, then you have to
access it in the `start` method after dependency injection has occurred.

Sometimes it is useful to write a constructor function to initialize the
component. If that constructor needs access to the config it must be passed
to the function, not provided as a dependency.

On Sat, Apr 6, 2024, 1:00 AM dieter.v...@gmail.com <
dieter.van.ees...@gmail.com> wrote:

> Hello,  I'm playing a bit with the 'Component' library. The system has
> some initial configuration (port numbers, uri's, usernames,...) in code.
>
> I'm doubting to eighter pass configuration when constructing the system:
> (C/system-map
>  :mycomponent  (map->MyComponent {:conf ...})
>
> OR to pass configuration itself as a component
> (defrecord Config ...)
> (C/system-map
> :config ...
> :mycomponent
>(C/using (map->MyComponent ...) [:config])
>
> Is there any reason why to prefer one way over the  other or is it just
> personal preference?
>
> kind regards,
> Dieter
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/clojure/2abcf943-e885-4e17-9856-0247959115dcn%40googlegroups.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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/CADQBrAT3fcv10bbwESWf8AHJouzx_nKrTZbO9BZ04%3DoKMrH19g%40mail.gmail.com.


Re: variable name duplicate

2022-07-30 Thread Paul Stadig
I'm pretty sure what is happening is the Clojure compiler is munging "x-"
into "x_" but since you already have an "x_" you get an exception.

On Sat, Jul 30, 2022, 5:23 AM vinurs  wrote:

> hello,
> i have the following code:
> ```
> (let [x- 1 x_ 2] (fn [] [x- x_])) ; => Throws: Duplicate field name "x_"
> with signature "J" in class file [...]
> ```
> i tested from clojure 1.0.0 to the latest, all throw the exception
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/clojure/72a4df10-b0a7-4886-b1aa-79e15f1f9c79n%40googlegroups.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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/CADQBrAQJK09mdp%3DLSTkUyEXFzNmQ78P-vU%3DbfjfgfVNjtKDZKA%40mail.gmail.com.


Re: [?] alter-var-root and *out*

2021-09-01 Thread Paul Stadig
`*out*` may have a thread binding established. REPLs will often do this.

If `*out*` is thread bound you should be able to use `thread-bound?` to
check that and then `set!` to set it, but you have to be careful because
https://clojure.atlassian.net/browse/CLJ-1077

On Wed, Sep 1, 2021 at 4:58 AM Philos Kim  wrote:

> I can change my dynamic var with alter-var-root like this.
>
> (def ^:dynamic *x* "abc")
> (alter-var-root #'*x* (constantly "xyz"))
> *x*
> ; => "xyz"
>
>
> However, I cannot change *out* with alter-var-root.
>
> (alter-var-root #'*out* (constantly "xyz"))
> *out*
> ; => #object[java.io.PrintWriter 0x6957ec80 "java.io.PrintWriter@6957ec80
> "]
>
>
> I expected the result to be "xyz" but the result of *out* doe not change
> at all
>
> Can anyone explain to me why?
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/clojure/23d13e9b-6eb8-4a39-b00d-8fead541e18en%40googlegroups.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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/CADQBrARn_ysTOsvk-CVrekb69k-ZMyxmNa%2BEcMZB_kabCykLKw%40mail.gmail.com.


Re: Strange result for clojure.core/time

2020-04-11 Thread Paul Stadig
The output of `time` is in milliseconds and the output of
`with-timer-print` is in seconds. So to make them comparable:
`time` 0.01344 msec
`time` with eval 0.922536 msec

`with-timer-print` 0.048 msec
`with-timer-print` with eval 1.041 msec

The `with-timer-print` version is slower, and I suspect it is the use of
`format` instead of `str`.

Paul

On Fri, Apr 10, 2020 at 8:46 PM Alan Thompson  wrote:

> I was doing some macro work and was curious about the cost of an inline
> `eval` vs compiled code.  I tried to time it with `clojure.core/time` and
> got results I can't explain:
>
>
> (println :eval-time)
> (time
>   (do
> (println (eval (quote (+ 40 0
> (println (eval (quote (+ 40 1
> (println (eval (quote (+ 40 2
> (println (eval (quote (+ 40 3
> (println (eval (quote (+ 40 4))
>
>
> :eval-time
> 40
> 41
> 42
> 43
> 44
> "Elapsed time: 0.922536 msecs"
>
> On a modern computer, this is an insanely long amount of time. And yes, it
> is approx 5x longer than doing just one line of the above.  I also tried it
> without the eval:
>
> (println :add-time)
> (time
>   (do
> (println (+ 30 0))
> (println (+ 30 1))
> (println (+ 30 2))
> (println (+ 30 3))
> (println (+ 30 4
>
>
> :add-time
> 30
> 31
> 32
> 33
> 34
> "Elapsed time: 0.01344 msecs"
>
> Still seems pretty slow to just print 5 lines with a single addition each.
>
> The `time` macro is very simple, and is often used as introductory example
> of how macros work and when they are needed:
>
> (defmacro time
>   "Evaluates expr and prints the time it took.  Returns the value of
>  expr."
>   {:added "1.0"}
>   [expr]
>   `(let [start# (. System (nanoTime))
>  ret# ~expr]
>  (prn (str "Elapsed time: " (/ (double (- (. System (nanoTime)) start#)) 
> 100.0) " msecs"))
>  ret#))
>
>
> I coincidentally had a homegrown timer available with nearly identical
> code.  It has results:
>
> (prof/with-timer-print :add-prof
>   (do
> (println (+ 10 0))
> (println (+ 10 1))
> (println (+ 10 2))
> (println (+ 10 3))
> (println (+ 10 4
>
>
> 10
> 11
> 12
> 13
> 14
> :with-timer-print :add-prof 0.48
>
>
>
> and
>
> (prof/with-timer-print :eval-prof
>   (do
> (println (eval (quote (+ 20 0
> (println (eval (quote (+ 20 1
> (println (eval (quote (+ 20 2
> (println (eval (quote (+ 20 3
> (println (eval (quote (+ 20 4))
>
>
> 20
> 21
> 22
> 23
> 24
> :with-timer-print :eval-prof 0.001041
>
> So we see the times are much, much shorter.  The timing code is nearly
> identical to clojure.core/time:
>
> (defmacro with-timer-result
>   "Times execution of Clojure forms, returning a result map like:
>   {:result result  :seconds seconds} "
>   [& forms]
>   `(let [start#   (System/nanoTime)
>  result#  (do ~@forms)
>  stop#(System/nanoTime)
>  elapsed# (double (- stop# start#))
>  seconds# (/ elapsed# 1e9)]
>  {:result  result#
>   :seconds seconds#}))
>
> (defmacro with-timer-print
>   "Times execution of Clojure forms, printing the result to the screen. "
>   [id & forms]
>   (when-not (keyword? id)
> (throw (ex-info "id must be a keyword" (vals->map id
>   `(let [result-map# (with-timer-result ~@forms)]
>  (println (format ":with-timer-print %s %12.6f" ~id (grab :seconds 
> result-map#)))
>  (grab :result result-map#)))
>
>
> Does anyone have an idea of why `clojure.core/time` gives such insanely
> inflated results?
>
> Alan
>
> PS.  I ran the above 4 sequences multiple times using lein-test-refresh,
> and these were the shortest I could get.  I'm pretty confident the answer
> is not loading, compiling, or JIT related.
>
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/clojure/CAN67zA0wp8vv6xbWDAPTFNrz8CpcDOv7o0_eY9%3DYxYqNdZY1RQ%40mail.gmail.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 ema

Re: with-open pattern

2017-05-10 Thread Paul Stadig
Hey Brian,
The fact that a reducible (as I have implemented it in the reducible-stream 
library) will fully realize itself if it is used as a sequence is a 
drawback that I'm not happy with. In the back of my mind I believe there 
may be a way around it, but I'm not sure, and it is still a topic of 
further thought/research for me. However, I think it can easily be avoided.

The point of using a reducible instead of a sequence is to invert the 
control so that the collection is in charge of processing itself. When you 
use a reducible as a sequence you are processing the collection externally, 
making the collection responsible only for doling itself out one item at a 
time, which it cannot do if it must also manage the scope for some resource 
(like a connection) that must be closed.

I would suggest that you have more processing that needs to be pushed into 
the reduction process. So, instead of getting a database result set, 
processing it in some way, and then trying to pass it as a sequence into 
Ring (I'm not sure if this is exactly your problem, but I think it is 
representative?), where Ring will want to consume that sequence, which will 
trigger it to fully realize in memory---instead push the work that Ring 
would be doing into the reduction process. So, reduce over the result set 
with an output stream (or one end of a piped output stream), and in the 
reduction process write to the stream. Ring takes the other end of the pipe 
and consumes the stream to produce its result.

A reducible is a delayed computation, and with transducers or by other 
means you can layer more delayed computation onto the reducible. As soon as 
you fire the reducible it will produce its entire result, whether the 
firing is because of a call to `reduce` or `seq`. A reducible is like a 
spring with potential energy built in, and when it is sprung it springs. A 
lazy sequence is like a wheel, if you apply external force to it, it will 
turn, but otherwise it is inert. Probably a terrible analogy, but that's 
the best I can come up with. :)

I hope that's helpful.


Paul

http://www.realworldclojure.com/
http://paul.stadig.name/
@pjstadig

On Thursday, May 4, 2017 at 3:04:40 PM UTC-4, Brian Craft wrote:
>
> It's definitely the same problem, but I don't think it helps me. This 
> part, in particular:
>
> "If you treat this object like a sequence, it will fully consume the input 
> stream and fully realize the decoded data in memory."
>
> I'm specifically trying to avoid realizing the full collection in memory, 
> because it won't fit.
>
> On Thursday, May 4, 2017 at 11:22:36 AM UTC-7, Josh Tilles wrote:
>>
>> I think the “reducible streams” approach described by Paul Stadig here 
>> <http://paul.stadig.name/2016/08/reducible-streams.html> has potential. 
>> It might not cover all of the scenarios you’re thinking of, though.
>>
>> On Thursday, May 4, 2017 at 1:35:48 PM UTC-4, Brian Craft wrote:
>>>
>>> The with-open style is used a lot in the jdbc lib, and elsewhere. It's 
>>> pretty simple when data is very small, as you can just evaluate the entire 
>>> result with doall, etc.
>>>
>>> How do you deal with larger data, where you need to evaluate 
>>> iteratively? If there's only one with-open it can be reasonably simple to 
>>> pass the consumer into that context (though from ring it's pretty 
>>> convoluted, due to needing to pass control to ring first). But if there are 
>>> multiple with-open you have to nest them, with a continuation passing 
>>> style, or middleware pattern, or something, which quickly becomes onerous 
>>> as it affects all the code surrounding the with-open.
>>>
>>> Is there some simpler pattern?
>>>
>>

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


[ANN] pjstadig/reducible-stream 0.1.0

2016-08-19 Thread Paul Stadig
I have released a library for fusing a stream, decoder, and resource 
management into a reducible object with the intent to automatically manage 
resources. You can then apply a transducer to this object. This means you 
can apply a transducer pipeline that only partially consumes the stream, 
yet will close the stream nonetheless.

You can also use this object as a sequence, though in that case it will 
load the entire decoded sequence into memory at the same time. There's a 
big difference between `(into [] (take 1) (decode-edn! stream))` and `(take 
1 (decode-edn! stream))`.

The library is called pjstadig/reducible-stream, and is at 
https://github.com/pjstadig/reducible-stream/

There is also a blog post covering the concepts: 
http://paul.stadig.name/2016/08/reducible-streams.html

I hope others find this useful. It's somewhat experimental, so caveat 
emptor. I welcome feedback.


Cheers!
Paul

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

2014-02-19 Thread Paul Stadig
On Wednesday, February 19, 2014 10:50:54 AM UTC-5, Michael Klishin wrote:
>
>
> Paul,
>
> I believe last time candidates from non-US timezones were not considered.
> Is it still the case? I'm pretty sure plenty of potential candidates on 
> this list care to know.
>

We like to be able to pair (this is especially helpful on a distributed 
team for preventing isolation as much as anything else). So the short 
answer is if someone is willing to work US hours (pick a timezone), then it 
could work. We may be interested in hiring in other timezones at some 
point, but that's the story for now.


Paul

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


Hiring Clojure developers for our distributed team at Outpace Systems

2014-02-19 Thread Paul Stadig
Hey everyone,
A couple of months ago Alexey posted a notice about Outpace hiring, and I 
got caught in his net. :) We are looking to hire more people in the next 
few months.

If you are interested in working from home on a distributed team writing 
Clojure code, then feel free to contact me. If you aren't quite sure how 
the distributed team thing works, or are concerned about your Clojure skill 
level etc, then please still feel free to contact me. Not everyone at 
Outpace has a background in Clojure. We want to work with people that are 
smart and fun and have different skills than ourselves.

Whatever the case, I'm happy to talk for 5-10 minutes, and if that doesn't 
result in hiring, then at least I made a new friend, right? :) I can do 
Skype, Google Hangouts, e-mail, IRC, whatever works for you.


Paul Stadig

p...@stadig.name
paul.sta...@outpace.com
http://github.com/pjstadig/
http://twitter.com/pjstadig/
pjstadig on freenode
pjstadig on Skype

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


Re: ANN: byte vector backed, utf8 strings for Clojure

2013-11-07 Thread Paul Stadig
On Thursday, November 7, 2013 2:57:03 PM UTC-5, Andy Fingerhut wrote:
>
> Very cool.
>
> I read through your README (thank you for that), and did not notice an 
> answer to the question of: does seq on a utf8 string return a sequence of 
> Unicode code points?  Java UTF-16 code points (with pairs of them for 
> characters outside the BMP)?  Something else?  It would be great to have 
> the answer in the README.
>

The utf8 strings implement the CharSequence interface, and when seq'ed 
produce a sequence of characters. In both those cases "characters" refers 
to Java UTF-16 character values, which means anything outside the BMP would 
be represented as surrogate pairs. Maybe I was assuming too much using 
those terms? I can clarify the README.

One idea I had for such a thing was: if any operation ever traversed part 
> of such a variable-bytes-per-char string for any reason (e.g. counting its 
> length in Unicode code points, or indexing), maintain some kind of data 
> structure mapping a few selected index values to their byte offset within 
> the byte array.  For example, a string containing 100 Unicode code points 
> might have byte offsets for the start of the UTF-8 encodings of every 32 
> code points, or 64.  This limits any sequential scanning to be from the 
> most recent cached byte offset.  Not a trivial amount of implementation 
> work, I know, but would be cool.
>

Even if you used full 32-bit integers to represent code points (even though 
code points are only 21-bit values...*sigh*) you still can't count 
"characters" in constant time, unless you define characters to mean code 
points (like you say above), because code points can represent combining 
marks which together represent a single character. You could 
create/maintain some kind of index for an encoded sequence of code points, 
but there's always a space/time tradeoff, and ultimately it will depend on 
your use case. If you mostly access strings sequentially, then utf8 isn't 
so bad. You can index into the middle of the stream find your way to the 
beginning of the next code point, and skip through code points from there. 
Not to say there's no merit to your idea. I've had the same myself. It 
would be nice to be able to jump to the nth encoded code point in a utf8 
string.

I have a book called "Unicode Demystified" and recommend it. It talks about 
what terms people use (like character vs. code point vs. glyph). It talks 
about some of the history of Unicode, and some practical tips like data 
structures that can be used to represent code points in memory for 
different types of tasks.

Anyway, Unicode is much for complex than any of us could hope, but I 
digress.


Paul

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


ANN: byte vector backed, utf8 strings for Clojure

2013-11-07 Thread Paul Stadig
I have released a byte vector backed, utf8 string library for Clojure. It
exists because when doing lots of ASCII string processing, Java strings can
be pretty hefty. Using byte arrays to represent strings can be annoying for
various reasons (mutability, bad equality semantics). However, byte vectors
are persistent data structures that store byte values efficiently. Some
interesting points:

* these strings implement the CharSequence interface, so you can use most
every clojure.string function with them, and you can match regular
expressions against them, which is pretty cool.
* in addition to the efficient storage, since they are persistent data
structures you also get structure sharing
* the library includes a "StringWriter" that will write directly to a utf8
string, so you don't even have to go through Java Strings if you don't want
to
* utf8 strings can be seq'ed and are lazily decoded as you traverse them
* also because they are persistent data structures you can use conj and
into with them

I think that's most of the salient features. The README has more details
and examples.


https://github.com/pjstadig/utf8


Cheers,
Paul

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


Re: JVM assertions in Clojure

2013-10-14 Thread Paul Stadig
So it turns out it is possible to have runtime disabled assertions in
Clojure without a compiler change, but I don think it is possible to have
assertions that can be disabled per package without a compiler change (if
at all).

I have released a new library that allows you to globally enable/disable
assertions at runtime in Clojure without any penalty.

https://github.com/pjstadig/assertions


Paul


On Mon, Oct 14, 2013 at 2:37 PM, Paul Stadig  wrote:

> On Mon, Oct 14, 2013 at 5:59 AM, Phillip Lord <
> phillip.l...@newcastle.ac.uk> wrote:
>
>>  writes:
>>
>> Same trick as
>> Java -- optimise the check away at compile time.
>>
>> Indeed, this is how Clojure's assert works.
>>
>
> This is the way Clojure's assert works (by compiling away the assertion).
> This is not the way Java assertions work. Java assertions can be turned off
> at runtime with zero performance penalty using a command line flag. The way
> they work is: the body of the assert is made conditional on a static final
> field of the class, the static initializer for said class will set that
> static final field to true or false depending on the command line flag, at
> runtime the JIT compiler notices that the static final field is set to
> false and could never be set to true and it eliminates the body of the
> assert as dead code.
>
> Java assertions are not compiled away by the Java compiler at compile
> time. They are compiled away by the JIT compiler at runtime.
>
> Compiling assertions away at compile time isn't so bad, but there are two
> problems: 1) it would be nice to be able to enable/disable assertions at
> runtime like Java does, 2) there isn't actually a good way to tell the
> compiler to turn assertions off. About the best you can do is set! *assert*
> to false in your namespace, but this causes problems when the code is
> AOT'ed or loaded in any context where *assert* does not have a binding
> established. You could also alter-var-root *assert* in a user.clj file,
> which also has problems (like the wholesale global disabling of asserts for
> every namespace not to mention the non-composability of user.clj).
>
>>
>> I think that you are worried about the overhead unnecessarily, though.
>> The assert status is checked at macro expansion time. If per module
>> switching on and off is what then I would suggest that you build on top
>> of the existing assert.
>>
>
> There is a huge performance penalty for Clojure assertions, if you don't
> compile them away, and there isn't really an easy way to compile them away.
> I know this because I wrote a persistent datastructure in Java and rewrote
> it in Clojure comparing their performance (using assertions both times). It
> was because of the performance penalty of Clojure's assertions that I wrote
> the message to the clojure-dev mailing list (and also wrote my own assert
> macro that I could toggle easily).
>

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


Re: JVM assertions in Clojure

2013-10-14 Thread Paul Stadig
On Mon, Oct 14, 2013 at 5:59 AM, Phillip Lord
wrote:

>  writes:
>
> Same trick as
> Java -- optimise the check away at compile time.
>
> Indeed, this is how Clojure's assert works.
>

This is the way Clojure's assert works (by compiling away the assertion).
This is not the way Java assertions work. Java assertions can be turned off
at runtime with zero performance penalty using a command line flag. The way
they work is: the body of the assert is made conditional on a static final
field of the class, the static initializer for said class will set that
static final field to true or false depending on the command line flag, at
runtime the JIT compiler notices that the static final field is set to
false and could never be set to true and it eliminates the body of the
assert as dead code.

Java assertions are not compiled away by the Java compiler at compile time.
They are compiled away by the JIT compiler at runtime.

Compiling assertions away at compile time isn't so bad, but there are two
problems: 1) it would be nice to be able to enable/disable assertions at
runtime like Java does, 2) there isn't actually a good way to tell the
compiler to turn assertions off. About the best you can do is set! *assert*
to false in your namespace, but this causes problems when the code is
AOT'ed or loaded in any context where *assert* does not have a binding
established. You could also alter-var-root *assert* in a user.clj file,
which also has problems (like the wholesale global disabling of asserts for
every namespace not to mention the non-composability of user.clj).

>
> I think that you are worried about the overhead unnecessarily, though.
> The assert status is checked at macro expansion time. If per module
> switching on and off is what then I would suggest that you build on top
> of the existing assert.
>

There is a huge performance penalty for Clojure assertions, if you don't
compile them away, and there isn't really an easy way to compile them away.
I know this because I wrote a persistent datastructure in Java and rewrote
it in Clojure comparing their performance (using assertions both times). It
was because of the performance penalty of Clojure's assertions that I wrote
the message to the clojure-dev mailing list (and also wrote my own assert
macro that I could toggle easily).

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


Re: [ANN] scopes: a little library for resource scopes

2013-10-13 Thread Paul Stadig
No, I just implemented a simple intuitive scope, which looks like it is
about the same as the basic idea there. There are some interesting
ideas/questions about how scopes work across threads and how consumers can
pass the buck for resource clean up to an enclosing scope (like exception
handling).

In my case I explicitly don't handle extending scopes to child threads (for
now). If the bindings convey to a child thread and you try to add an object
to the current scope, then you'll get an exception for trying to set! a
conveyed binding.

I'm not sure about the idea for passing resource clean up to an enclosing
scope. I'd have to consider the problem and potential solutions before I
could form an opinion.

That's not to say that these things are bad ideas or that some version of
them won't end up in the library. I just wanted a minimal implementation of
a scoping concept. It can evolve from there.


Paul


On Sat, Oct 12, 2013 at 10:11 AM, Jozef Wagner wrote:

> Is it based on http://dev.clojure.org/display/design/Resource+Scopes ?
>
> On Friday, October 11, 2013 3:54:59 PM UTC+2, Paul Stadig wrote:
>>
>> It separates the resource management from the creation and lexical
>> binding of resources. You can create a scope high up in the call stack, and
>> within the dynamic extent of that scope you can create resources, return
>> them from functions and freely use them; when the scope eventually exits,
>> then the resources will be cleaned up.
>>
>> This library does also generalize a bit to allow you to register an
>> object and a clean up function, or even just a thunk to get called when the
>> scope exits.
>>
>> On Friday, October 11, 2013 7:56:52 AM UTC-4, Cedric Greevey wrote:
>>>
>>> What does this do that (with-open ...) doesn't do? Generalize to other
>>> cleanup methods than (.close x)?
>>>
>>>
>>> On Fri, Oct 11, 2013 at 6:36 AM, Paul Stadig  wrote:
>>>
>>>> I have released version 0.1.0 of scopes, a little library for resource
>>>> scopes. It can be used to establish a resource scope with the
>>>> with-resource-scope macro. Within the dynamic extent of that macro one can
>>>> register a resource with the scoped! function so that when the macrco block
>>>> goes out of scope .close is called on the registered resource.
>>>>
>>>> An object and function can also be registered with (scoped! x (fn [x]
>>>> ...)) so that when the macro block goes out of scope the function will be
>>>> called and given x as an argument.
>>>>
>>>> There is also a shorthand function called scoped-thunk! that will
>>>> register a thunk (a function taking no arguments) to be called when the
>>>> macro block goes out of scope.
>>>>
>>>> The scopes library also defines a function named closeable? that will
>>>> return true if its argument implements java.lang.AutoCloseable.
>>>>
>>>> Because scopes uses the java.lang.AutoCloseable interface and the
>>>> exception supression mechanism, it is only compatible with Java 7.
>>>>
>>>> Finally, there is also a scopes-magic artifact, and when it is on the
>>>> classpath it will automatically pull in the scopes library and add
>>>> with-resource-scope, scoped!, scoped-thunk!, and closeable? to clojure.core
>>>> so that they are automatically available everywhere with out having to be
>>>> imported. I'm not saying that this is necessarily a good idea, but there it
>>>> is. :)
>>>>
>>>> https://clojars.org/pjstadig/**scopes<https://clojars.org/pjstadig/scopes>
>>>> https://clojars.org/pjstadig/**scopes-magic<https://clojars.org/pjstadig/scopes-magic>
>>>>
>>>>
>>>> Paul
>>>>
>>>>  --
>>>> --
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Clojure" group.
>>>> To post to this group, send email to clo...@googlegroups.com
>>>> Note that posts from new members are moderated - please be patient with
>>>> your first post.
>>>> To unsubscribe from this group, send email to
>>>> clojure+u...@googlegroups.com
>>>> For more options, visit this group at
>>>> http://groups.google.com/**group/clojure?hl=en<http://groups.google.com/group/clojure?hl=en>
>>>> ---
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Clojure" group.
>>>> To unsubscri

Re: [ANN] scopes: a little library for resource scopes

2013-10-11 Thread Paul Stadig
It separates the resource management from the creation and lexical binding 
of resources. You can create a scope high up in the call stack, and within 
the dynamic extent of that scope you can create resources, return them from 
functions and freely use them; when the scope eventually exits, then the 
resources will be cleaned up.

This library does also generalize a bit to allow you to register an object 
and a clean up function, or even just a thunk to get called when the scope 
exits.

On Friday, October 11, 2013 7:56:52 AM UTC-4, Cedric Greevey wrote:
>
> What does this do that (with-open ...) doesn't do? Generalize to other 
> cleanup methods than (.close x)?
>
>
> On Fri, Oct 11, 2013 at 6:36 AM, Paul Stadig 
> > wrote:
>
>> I have released version 0.1.0 of scopes, a little library for resource 
>> scopes. It can be used to establish a resource scope with the 
>> with-resource-scope macro. Within the dynamic extent of that macro one can 
>> register a resource with the scoped! function so that when the macrco block 
>> goes out of scope .close is called on the registered resource.
>>
>> An object and function can also be registered with (scoped! x (fn [x] 
>> ...)) so that when the macro block goes out of scope the function will be 
>> called and given x as an argument.
>>
>> There is also a shorthand function called scoped-thunk! that will 
>> register a thunk (a function taking no arguments) to be called when the 
>> macro block goes out of scope.
>>
>> The scopes library also defines a function named closeable? that will 
>> return true if its argument implements java.lang.AutoCloseable.
>>
>> Because scopes uses the java.lang.AutoCloseable interface and the 
>> exception supression mechanism, it is only compatible with Java 7.
>>
>> Finally, there is also a scopes-magic artifact, and when it is on the 
>> classpath it will automatically pull in the scopes library and add 
>> with-resource-scope, scoped!, scoped-thunk!, and closeable? to clojure.core 
>> so that they are automatically available everywhere with out having to be 
>> imported. I'm not saying that this is necessarily a good idea, but there it 
>> is. :)
>>
>> https://clojars.org/pjstadig/scopes
>> https://clojars.org/pjstadig/scopes-magic
>>
>>
>> Paul
>>
>>  -- 
>> -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@googlegroups.com
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+u...@googlegroups.com 
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to clojure+u...@googlegroups.com .
>> For more options, visit https://groups.google.com/groups/opt_out.
>>
>
>

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


[ANN] scopes: a little library for resource scopes

2013-10-11 Thread Paul Stadig
I have released version 0.1.0 of scopes, a little library for resource 
scopes. It can be used to establish a resource scope with the 
with-resource-scope macro. Within the dynamic extent of that macro one can 
register a resource with the scoped! function so that when the macrco block 
goes out of scope .close is called on the registered resource.

An object and function can also be registered with (scoped! x (fn [x] ...)) 
so that when the macro block goes out of scope the function will be called 
and given x as an argument.

There is also a shorthand function called scoped-thunk! that will register 
a thunk (a function taking no arguments) to be called when the macro block 
goes out of scope.

The scopes library also defines a function named closeable? that will 
return true if its argument implements java.lang.AutoCloseable.

Because scopes uses the java.lang.AutoCloseable interface and the exception 
supression mechanism, it is only compatible with Java 7.

Finally, there is also a scopes-magic artifact, and when it is on the 
classpath it will automatically pull in the scopes library and add 
with-resource-scope, scoped!, scoped-thunk!, and closeable? to clojure.core 
so that they are automatically available everywhere with out having to be 
imported. I'm not saying that this is necessarily a good idea, but there it 
is. :)

https://clojars.org/pjstadig/scopes
https://clojars.org/pjstadig/scopes-magic


Paul

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


Re: JVM assertions in Clojure

2013-10-11 Thread Paul Stadig
As reflected in the linked discussion and Jira ticket, it seems possible to 
be able to use -ea/-da with Clojure. It would definitely require a compiler 
change, and I'm not aware of any further movement to make Clojure's asserts 
use a mechanism compatible with -ea/-da.

An additional annoyance (as I mentioned in the linked thread) is that there 
isn't really a way to easily disable assertions. Clojure supports some 
properties for configuring compilation 
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compile.java#L28-L30
 
but not a property to enable/disable assertions.

I've worked around it before by defining my own assert macro and using 
(refer-clojure :exclude [assert]), in order to be able to toggle assertions 
myself. 
https://github.com/pjstadig/deque-clojure/blob/master/src/name/stadig/deque.clj#L23-L27


Paul

On Thursday, October 10, 2013 4:43:55 PM UTC-4, lop...@gmail.com wrote:
>
> Dear All,
>
> Is it possible to use Java assertion system in Clojure?
>
> I want to put invariant checks in my code which can be turned on/off at
> runtime with java -ea/-da.
>
> http://docs.oracle.com/javase/7/docs/technotes/guides/language/assert.html
>
> The only mention touching this issue in Clojure I could find is
>
> https://groups.google.com/forum/#!topic/clojure-dev/kUCVUEALmWI
>
> it does not give any constructive suggestions, though.
>
> Has anybody used this JVM facility in Clojure code?
>
> Thanks in advance for any of your hints!
>
> Best regards,
> Michal
>
>

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


Re: JVM assertions in Clojure

2013-10-11 Thread Paul Stadig
The problem is that you would still have a performance hit. As I 
understand, the reason that Java assertions have no runtime penalty when 
disabled is because they depend on the value of a final field in a class 
which the JIT will eliminate as dead code when that final field is set to 
false. The only way to get Clojure's asserts eliminated at runtime would 
seem to require a compiler change.

Paul

On Friday, October 11, 2013 7:02:24 AM UTC-4, Phillip Lord wrote:
>
> > writes: 
> > Is it possible to use Java assertion system in Clojure? 
> > 
> > I want to put invariant checks in my code which can be turned on/off at 
> > runtime with java -ea/-da. 
> > 
> > 
> http://docs.oracle.com/javase/7/docs/technotes/guides/language/assert.html 
> > 
> > The only mention touching this issue in Clojure I could find is 
> > 
> > https://groups.google.com/forum/#!topic/clojure-dev/kUCVUEALmWI 
> > 
> > it does not give any constructive suggestions, though. 
> > 
> > Has anybody used this JVM facility in Clojure code? 
> > 
> > Thanks in advance for any of your hints! 
>
>
> I guess you could use the assertion status of Java to set the *assert* 
> variable, and then just use the Clojure assert facility. 
>
> Unfortunately this is a bit of a pain as there doesn't appear to be an 
> API to check the assertion status. So, you'd need a bit of java code... 
>
>
> static boolean assertsEnabled(){ 
> boolean assertsEnabled = false; 
> assert assertsEnabled = true;   
>
> return assertedEnabled; 
> } 
>
> Bit ugly. 
>

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


Re: Performance issue with hashing records

2013-02-04 Thread Paul Stadig
On Sunday, February 3, 2013 9:56:49 PM UTC-5, puzzler wrote:
>
> In these examples, the map/record is freshly created each time through the 
> loop, so caching should not be a factor.  
>

Good point. So maybe it's not the caching :).

Another factor is that literal hashmaps are actually PersistentArrayMaps. 
If you use PersistentHashMaps instead of PersistentArrayMaps you get 
similar performance:

Clojure 1.5.0-RC4
user=> (class {:x "a" :y 3})
clojure.lang.PersistentArrayMap
user=> (time (dotimes [n 1000] (hash (hash-map :x "a" :y 3
"Elapsed time: 3315.031872 msecs"
nil


Paul

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




Re: Performance issue with hashing records

2013-02-03 Thread Paul Stadig
On Sunday, February 3, 2013 1:07:41 AM UTC-5, puzzler wrote:
>
> I just went through the process of converting my map-based program over to 
> records, hoping it would improve speed.  Much to my dismay, it actually 
> slowed my program down substantially.  With some profiling, I discovered 
> that one possible explanation is that (at least in RC4) hashing of records 
> is about 60x slower than their map-based counterpart.
>
> (defrecord A [x y])
> => (time (dotimes [n 1000] (hash {:x "a" :y 3})))
> "Elapsed time: 90.631072 msecs"
> => (time (dotimes [n 1000] (hash (A. "a" 3
> "Elapsed time: 5549.788311 msecs"
>
> Any thoughts about why this is the case?
>

There was a change for 1.5 to cache hasheq for maps 
https://github.com/clojure/clojure/commit/d77489d3ce912c177fe288a6f399a5c1da6683db
 
but the same is not done for defrecords. That is why maps are so much 
faster than records.


Paul

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




ANN: nio 0.0.4

2013-01-29 Thread Paul Stadig
Wanted to let everyone know that I've released nio 0.0.4 on Clojars.
nio is a library that extends clojure.java.io support to the java.nio
classes. The 0.0.4 release adds two convenience functions for reading
and setting the byte order of ByteBuffers. You can find out details
and example usage at http://github.com/pjstadig/nio/ and you can find
the Changelog here
https://github.com/pjstadig/nio/blob/master/CHANGELOG.org.


Paul

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




Re: Auto-indentation not working with clojure-mode 2.0.0

2013-01-01 Thread Paul Stadig
This was an intentional change. 
https://github.com/technomancy/clojure-mode/pull/89

On Jan 1, 4:15 am, Richard Elliott 
wrote:
> I've just installed emacs and clojure-mode on a new machine. Out of the box
> auto-indentation did not work for me. I noticed that in the latest release
> of clojure-mode.el the RET keybinding has been removed.
>
> 1.11 had (define-key map (kbd "RET") 'reindent-then-newline-and-indent)
> 2.0.0 does not
> I put back in and recompiled clojure-mode.el and autoindentation started to
> work OK.
>
> Not sure if I've done something stupid or found a bug. Can anyone shed any
> light on this.
>
> Here's the change 
> itemhttps://github.com/technomancy/clojure-mode/commit/c2077d48858a507d03...
>
> Thanks

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


Re: ANN: polyfn

2012-10-09 Thread Paul Stadig
On Tuesday, October 9, 2012 9:37:20 AM UTC-4, tbc++ wrote:
>
> >> Polyfns are exactly as fast as protocol functions (I am using the same
> >> caching and dispatch code), but they do not generate a Java interface,
> >> and they are slightly simpler to define.
>
> So I guess I have to ask the question again...what is the true use case of 
> polyfns? Are they faster than multimethods?
>

Dramatically faster than multimethods, just like non-interface based 
protocol dispatch. It is the same code.
 

> If I can get a dramatic speed up by using interfaces, why would I throw 
> that away?
>

Sorry, I should have said that polyfns are exactly as fast as non-interface 
protocol dispatch. As with everything, it's all about tradeoffs. I don't 
recall that I said everyone should be replacing their uses of protocols 
with polyfns, so I don't know why I'm supposed to convince you to do so. I 
think it is useful to have fast polymorphic dispatch separate from class 
generation, and useful as an orthogonal building block with granularity at 
the function level. If you're interested in pure performance, then feel 
free to use protocols. There are downsides to that approach, too. I think 
maybe polyfns might be fast enough for most use cases, but I have some 
ideas for improving performance, too.

I've been experimenting with some Java 7 features. I have a stashed version 
of polyfns that use java.lang.ClassValue as a cache for implementation fns 
instead of a clojure.lang.MethodImplCache. The performance is pretty good, 
and the implementation is simpler.

I'm wondering what kind of performance I could eek out by having a 
ClassValue cache that caches MethodHandles to the implementations instead 
of the IFns themselves. Obviously Clojure isn't emitting invokedynamic call 
sites, but I wonder whether the JVM could inline through that kind of a 
call chain.


Cheers,
Paul

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

Re: ANN: polyfn

2012-10-09 Thread Paul Stadig
On Tuesday, October 9, 2012 7:24:57 AM UTC-4, Tassilo Horn wrote:
>
> I'm happy to have complemented my questions with at least a bit useful 
> feedback and pointers. :-) At least this latter point is a blocker for 
> trying to replace my protocols with polyfns right now. 
>

Yeah, thanks for the feedback. I've pushed a new version that separates the 
definition and extension mechanisms into defpolyfn and extend-polyfn forms. 
I also added add-impl, remove-impl, and reset-polyfn methods for modifying 
the dispatch table directly.

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

Re: ANN: polyfn

2012-10-09 Thread Paul Stadig
On Tue, Oct 9, 2012 at 2:40 AM, Tassilo Horn  wrote:
> Ah, so if I change a polyfn for a type X, the new behavior will only be
> available to new X instances, right?

If you change a polyfn implementation for a type X, then the new
behavior will be available to all instances of X, even those created
before you changed the polyfn. The new versus old instances issues
only manifest when you are generating new types with the same "name"
as defrecord and defprotocol do. In that case, instances created with
the old version of the defrecrod and defprotocol are actually
instances of a different type than instances created with the newly
compiled defrecord and defprotocol types.

> Well, as said, those are pretty stable, so it's no issue for me.  How
> about the growth of the dispatch table?  Say, I recompile a namespace
> containing polyfn definitions 50 times during a session, will that slow
> down dispatch noticeably?  Maybe you could store the current active
> definition form per type, so that identical definitions for the same
> type don't get added to the dispatch table?

Recompiling a polyfn definition 50 times will only end up with a
dispatch table of one entry. The multiple entries get added when you
recompile defrecord and defprotocol. When you recompile a defrecord
form 50 times you get 50 different types which is why the dispatch
table grows both for polyfns and for protocols.

> Oh, and here's a whishlist item: It should be possible to add a
> docstring to polyfns, and maybe also other metadata (:pre, :post, :tag,
> ...).  tools.macro/name-with-attributes makes that pretty easy.

Good point. I'll look into this.

> And another question: Since defpolyfn expands into a defonce form, does
> that mean that all (defpolyfn foo ...) forms have to be in the same
> namespace?  It looks to me that currently defining the same polyfn foo
> in different namespaces bar and baz will create bar/foo and baz/foo
> which have nothing to do with each other (you cannot `use` both bar and
> baz).  IMO, that would be an argument for splitting polyfns into a
> single declaration form and many definition forms providing
> implementations for several types (like defmulti and defmethod, or
> defprotocol and extend).

Haha a good point. I'll look into this issue. Looks like I will have
to split out the definition from the extension. Should be simple
enough.

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


Re: ANN: polyfn

2012-10-09 Thread Paul Stadig
On Mon, Oct 8, 2012 at 10:46 PM, Frank Siebenlist
 wrote:
> Interesting project, although I'm still a little unclear about the 
> "convincing" use cases where you would choose polyfn over protocols...
>
> Also, how does the polyfn implementation compare to the clojurescript 
> protocol implementation?

Not sure I could comment on that, since I've never used ClojureScript.

The point of polyfns was to separate out the dispatch from the class
generation. If you don't care about the class generation, then they
would both work just as well. If you need the class generation, then
you need protocols. If you need not class generation, then you need
polyfns. This is about simpler composable parts. Protocols could
conceivably have been built on something like polyfns, adding class
generation.

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


Re: ANN: polyfn

2012-10-08 Thread Paul Stadig
On Monday, October 8, 2012 1:55:50 PM UTC-4, Tassilo Horn wrote:
>
> Paul Stadig > writes: 
>
> Hi Paul, 
>
> > I created a library for Clojure to do open, single dispatch 
> > polymorphism. What does this mean? 
> > 
> > * A polyfn dispatches on the type of its first argument. 
> > * You can add an implementation for a new type to an existing polyfn. 
> > * You can define a new polyfn on an existing type. 
> > 
> > Polyfns are exactly as fast as protocol functions (I am using the same 
> > caching and dispatch code), but they do not generate a Java interface, 
> > and they are slightly simpler to define. 
>
> Sounds cool. 
>
> I have a bunch of mostly one-method-protocols that I extend upon 
> existing (95% java) types.  I don't rely on the existence of the 
> protocol interfaces, and neither do I use extends?, satisfies?, or 
> extenders. 
>
> Would it make sense to switch to polyfns?  Are there more advantages 
> except from the definitions being slightly more concise?
>

I can't say that you should necessarily switch to polyfns, but this was the 
kind of situation I was imagining. polyfns are the fast and open type based 
dispatch decomplected from protocols, and I think that's the main 
advantage, simplicity.

A drawback with polyfns is there's no Java interface that can be extended 
in Java code to participate in the dispatch. The Java interface is nice, 
but as you mention below, the generation of interfaces can cause staleness 
issues especially when paired with defrecord. defprotocol and defrecord 
both generate a new class each time you compile them, because of the way 
classes, class loaders, and class identity work.

Another difference between protocols and polyfns is that everytime you 
compile a defprotocol form it regenerates the protocol functions, whereas a 
polyfn is generated once and never changes (only the dispatch table 
changes). This has implications though I'm not sure how much they matter. 
YMMV

One minor problem I have with the protocol approach is that if you 
> recompile a protocol during interactive development, then calling the 
> protocol methods on already existing instances in your repl session of 
> types on which the protocol has been extended won't work anymore.  Do 
> polyfns help there? 
>

defrecord will behave differently depending on how you extend the protocol. 
If you extend the protocol inline in the defrecord form, then the class 
that defrecord generates will implement the protocol interface. In this 
case nothing gets added to the protocol dispatch table, and instead 
dispatch happens through the Java interface. When you recompile the 
defprotocol form, it regenerates the Java interface and the protocol 
functions. The new functions it generates know only about the new 
interface, so they complain when you give it an instance of your defrecord 
that you had stashed away before you recompiled.

If you define a defrecord and extend a protocol to it using extend-protocol 
or extend-type it adds an entry to the dispatch table for the protocol. 
Since dispatch happens through the dispatch table instead of the interface, 
then when you recompile your defprotocol and defrecord your old instances 
continue to work, but because of the way class identity works they continue 
to dispatch to the implementation of the protocol that was defined when you 
created your instance. In order to invoke the new implementation of the 
protocol, you need to create a new instance of your defrecord. Every time 
you recompile your defrecord it adds a new entry to the protocol's dispatch 
table, so the table will contain a number of entries on the order of the 
number of times you have recompiled your defrecord.

Since polyfns do not generate a Java interface through which they dispatch, 
they will behave like this second case. Your old instances will continue to 
work, but with the polyfn implementation that was associated with the 
instance's class, and your dispatch table size will be on the order of the 
number of times you have recompiled the polyfn forms.

I'm not sure if this is better or worse than what happens in the first 
case, but I do know that in 100% of the cases where I've used protocols I 
have not really needed the Java interface. Though it also doesn't really 
hurt anything to have the interface around if you're not using it.

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

Re: ANN: polyfn

2012-10-08 Thread Paul Stadig
On Mon, Oct 8, 2012 at 11:33 AM, Timothy Baldridge  wrote:
>
>>> Define some implementations for specific types.
>>>
>>>  (require '[name.stadig.polyfn :refer [defpolyfn]])
>>>  (defpolyfn foo Long [exp] (inc exp))
>>>  (defpolyfn foo String [exp] "Hello, World!")
>
> I like the idea, but it seems to go against the pattern set by multi-fns:
>
> (defmulti foo...)
> (defmethod foo ...)
>
> Could we do some pattern like that?
>
> (defpolyfn foo...)
> (extendpolyfn foo ...)
>
> I'm thinking about situations like testing, repls, etc. When sometimes I
> actually do want to completely redefine the function. I'd like a way to
> re-create the polyfn.  From what I see above it looks like the creation of
> the polyfn is implicit rather than explicit.

At first I had that kind of syntax, but (just like multifns) if you
allowed defmulti to zap the dispatch table, then it would probably
make it more difficult to interactively write code with the repl and
recompiling a namespace. The only purpose of the defmulti is to define
the dispatch function, and in the case of polyfns the dispatch is
assumed to be on the type of the first argument, so it didn't seem
there was a need for (defpolyfn foo...) (extendpolyfn foo ...).

I've thought about whether there might be some use for a way to add
and remove implementations from the dispatch table, or perhaps reset
it. I'm open to ideas around this.


Paul

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


ANN: polyfn

2012-10-08 Thread Paul Stadig
I created a library for Clojure to do open, single dispatch
polymorphism. What does this mean?

* A polyfn dispatches on the type of its first argument.
* You can add an implementation for a new type to an existing polyfn.
* You can define a new polyfn on an existing type.

Polyfns are exactly as fast as protocol functions (I am using the same
caching and dispatch code), but they do not generate a Java interface,
and they are slightly simpler to define.

You can find polyfn here https://github.com/pjstadig/polyfn. You can
pull it using Leiningen like so:

 [name.stadig/polyfn "1.0.2"]

Or using Maven like so:

 
   name.stadig
   polyfn
   1.0.2
 

EXAMPLE:

Define some implementations for specific types.

 (require '[name.stadig.polyfn :refer [defpolyfn]])
 (defpolyfn foo Long [exp] (inc exp))
 (defpolyfn foo String [exp] "Hello, World!")

Use it.

 (foo 1) => 2
 (foo "string") => "Hello, World!"
 (foo 1.0) => #

Oops, there is no implementation for Double, let’s define one for
java.lang.Number.

 (defpolyfn foo Number [exp] Number)
 (foo 1.0) => java.lang.Number

The rest of the implementations remain the same

 (foo 1) => 2
 (foo "string") => "Hello, World!"

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


[ANN] nio: Clojure support for java.nio

2012-08-25 Thread Paul Stadig
I have done a little library to provide better support in Clojure for
java.nio. It covers three main areas: 1) extending clojure.java.io to
cover java.nio type where reasonable, 2) providing a set of coercion
functions for java.nio types (similar to those for java.io provided by
clojure.java.io), and 3) provides buffer-seq, buffer-nth, and
buffer-to-array so that Buffers can get some of the niceness of
Clojure's seq abstractions, etc.

I brought this topic up on the clojure-dev mailing list. I would like
to see the buffer-seq, buffer-nth, and buffer-to-array work integrated
better into Clojure, and there is still discussion happening around
that. Otherwise, this work could just remain a separate library, or
perhaps it could be rolled into clojure.java.io.

Whatever the case, please use it and I would appreciate any feedback.

https://github.com/pjstadig/nio
https://clojars.org/nio

Paul

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

2012-07-09 Thread Paul Stadig
On Mon, Jul 9, 2012 at 12:12 PM, Paul Stadig  wrote:
> On Mon, Jul 9, 2012 at 12:07 PM, Mark Probst  wrote:
>> Yes.  I'm sorry I forgot to mention that.  Please let me know if it
>> works and I'll update the README.
>
> It works with lein2. The tests are running now, but there are some
> failures. I'll keep poking at it.

The test failures seem to be because libgc wasn't on my
LD_LIBRARY_PATH. After I did that the tests all passed fine.


Paul

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

2012-07-09 Thread Paul Stadig
On Mon, Jul 9, 2012 at 12:07 PM, Mark Probst  wrote:
> Yes.  I'm sorry I forgot to mention that.  Please let me know if it
> works and I'll update the README.

It works with lein2. The tests are running now, but there are some
failures. I'll keep poking at it.

Thanks!
Paul

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

2012-07-09 Thread Paul Stadig
On Mon, Jul 9, 2012 at 11:50 AM, Mark Probst  wrote:
> On Mon, Jul 9, 2012 at 5:47 PM, Paul Stadig  wrote:
>> I checked out the code and followed the instructions to setup glib2
>> and the GC. When I run `lein test` "I get Exception in thread "main"
>> java.io.FileNotFoundException: Could not locate clojurec/
>> core__init.class or clojurec/core.clj on classpath:"
>>
>> Do you know what might be going wrong?
>
> No, I don't think so.  A stab in the dark: Are you using leiningen 2?

I'm using lein 1.7.1. Should I be using lein2?

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

2012-07-09 Thread Paul Stadig
Mark,
This looks interesting.  Thanks for working on this.

I checked out the code and followed the instructions to setup glib2
and the GC. When I run `lein test` "I get Exception in thread "main"
java.io.FileNotFoundException: Could not locate clojurec/
core__init.class or clojurec/core.clj on classpath:"

Do you know what might be going wrong?


Thanks,
Paul

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

2012-06-17 Thread Paul Stadig
On Jun 16, 11:37 am, David Nolen  wrote:
> Not possible in Clojure and a source of hassle in Scheme and Common Lisp.
> If you have dotted pairs you can never know if you have a proper list.

I'm probably missing some context, but I've heard this argument before
and had a hard time understanding it. Clojure is dynamically typed,
and you should expect that calling something like 'map with an
improper list would blow up just like you would expect this to blow
up:

user=> (map inc 5)
IllegalArgumentException Don't know how to create ISeq from:
java.lang.Long  clojure.lang.RT.seqFrom (RT.java:494)

With dotted pairs I would expect something like:

user=> (map inc '(5 6 . 7)))
IllegalArgumentException Don't know how to create ISeq from:
java.lang.Long  clojure.lang.RT.seqFrom (RT.java:494)

And in Racket you get:

> (map (lambda (x) (+ x 1)) 2)
map: expects type  as 2nd argument, given: 2; other
arguments were: #
> (map (lambda (x) (+ x 1)) '(1 . 2))
map: expects type  as 2nd argument, given: '(1 . 2);
other arguments were: #

I'm not necessarily arguing that Clojure should have dotted pairs. I
think something like [1 2] works well as a substitute.  Plus Clojure
already uses . for other things and the overloading might be
confusing. I'm just not sure I understand the typing argument for a
dynamically typed language.


Paul

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

2012-03-07 Thread Paul Stadig


On Sunday, October 23, 2011 5:21:52 PM UTC-4, Rich Hickey wrote:
>
> Hi all,
>
> This reply is to the thread, not Luc specifically.
>
> Thanks everyone for your feedback and input.
>
> I have pushed 3 commits:
>
> 1) Fixes the inconsistency between the hash function used by Clojure maps 
> (was .hashCode) and =. Thanks Paul for the report.
>
> 2) Changes core/hash to return the result of this hashing function. Thus, 
> it returns a different value than does .hashCode for Integers, Shorts, 
> Bytes and Clojure collections. Feedback welcome.
>
> 3) Only due to the first fix, it now becomes possible to box ints to 
> Integers without much grief. This commit implements that for evaluation 
> purposes, and is not a commitment to that policy. Note well that while in 
> the first commit the answer is clear, on this point there is always going 
> to be a tradeoff and there is no 'right' answer. 
>
> Here are the issues as I see them:
>
> First, note there is no 'following' of Java semantics as an objective. 
> Java semantics are that Integers are never equal to Longs, and I presume no 
> one wants to go back to that. 
>
> Second, boxing is a change of type, period. There is no valid complaint 
> that 'you changed my type'. int != Integer either.
>
> Third, there are 2 scenarios in consuming things you box in Clojure from 
> Java:
>
> a) You control the Java. In this case, having Clojure make everything 
> uniform (Longs) make things easier for you. There is no heterogeneousness 
> regardless of the source or manipulation of numbers, and can always expect 
> Longs.
>
> b) You don't control the Java. In this case you must match consuming 
> expectations i.e. conforming to Java promotion, types of generics etc. 
> ***This will *always* require vigilance and explicitness due to arithmetic 
> conversions etc***. Auto promotion is only one part. Note that this is true 
> in Java as well - while type checker may scold you, you still have to 
> cast/coerce on mismatch.
>  
> Even with the auto box change, you are only an arithmetic operation away 
> from having the problem again. For instance in the original report, 
> wrapping .getValue with dec generates an interop mismatch again:
>
> (let [amap {1 (dec (.getValue obj))}] …)
>
> There is no way we are going to 'fix' that by adopting Java's numeric 
> tower, which is dangerous and requires static types. The bottom line is 
> specific type requirements on the Java side require explicit boxing on 
> order to have correct and non-brittle code.
>
> The final consideration is collection equality. When Clojure autoboxes to 
> Longs, you get homogeneous collection contents, and thus .equals is still 
> true for the collection on the Java side,  vs random - 'depends on where I 
> got the contents from and what I did with them'. 
>
> FYI - there are the RT/box functions that box as per Java. These could be 
> exposed in Clojure.
>
> -
> In short, having autoboxing match Java does not really free you from your 
> responsibility to create specific boxed types when you need them on the 
> Java side. I.e., Clojure can't help you.
>
> On the flip side, when you are in charge of the Java code, Clojure's being 
> more consistent makes things more consistent on the other side and *does* 
> give you less to do to make sure things work.
>
> I prefer what we had (auto box to Longs), but I think it matters a 
> somewhat less now with = consistent hashing. If we decide to revert to that 
> we can discuss making auto boxing of short and byte consistent.
> -
>
Rich,
In Clojure 1.4.0-beta3 ints are boxed as Integers.

Clojure 1.4.0-beta3
user=> (map type [(byte 1) (short 1) (int 1) (long 1)])
(java.lang.Byte java.lang.Short java.lang.Integer java.lang.Long)

Based on the above and my conversation with you at the Conj you seemed to 
be pretty convinced that ints should be boxed as Longs. You made a 
temporary commit to box them as Integers 
(https://github.com/clojure/clojure/commit/a2e4d1b4eaa6dad26a1a96b9e9af129a9d10),
 
then Stu Halloway reverted it 
(https://github.com/clojure/clojure/commit/abfa803838a1884d0c5112bc6b876cf33a8a05cc),
 
then he reverted the revert 
(https://github.com/clojure/clojure/commit/798a98bc1b844b0fe08e9309886823cf7ca92604).

Are we still in the temporary period for evaluation purposes? Have you 
changed your mind? If so, I'd be interested to hear why. Should we expect 
this behavior from beta3 to change any time soon?


Paul

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

Sonian is looking for Clojure Developers

2012-01-03 Thread Paul Stadig
For the HR version you can visit this link:

http://www.sonian.com/about/careers/principal-software-engineer-cloud/

Here's the IMO version:

At Sonian, we have a great team working on interesting problems. Our
backend is written in Clojure and runs 100% on the cloud. We distribute
work across a cluster of compute nodes. We store over a petabyte of data on
S3. We index the data into a distributed search cluster to return subsecond
results across millions of indexed objects. We have an IRC bot (written in
Clojure) that does our bidding. We live in the future!

We are a remote team, and we get together in person a few times a year to
run amok in Boston.

Feel free to contact me (p...@stadig.name) if you have any question you'd
like to ask prior to responding to the job posting. Otherwise, send your
cover letter and resume to j...@sonian.net with the subject "Principal
Software Engineer, Cloud".


Happy New Year!
Paul Stadig

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

2011-10-23 Thread Paul Stadig
On Sun, Oct 23, 2011 at 4:01 PM, Luc Prefontaine <
lprefonta...@softaddicts.ca> wrote:

> It's simpler to use one representation to port the core. You can choose the
> fastest/efficient one. You do not have to carry all these intermediate
> types
> with you.
>

There are already at least two numeric types: long and BigInt. If you want
to try to be blissfully unaware of any of this, then you can use promoting
math (+' and friends). Adding more numeric types to the tower doesn't seems
to make things more complicated in the general case, only in the interop
case, or in the case that you are trying to optimize your code because it is
too slow or uses too much memory. Which is what we're talking about here.

You have said before that you grant there are interop cases at the edges of
Clojure, and they should be kept at the edge. What we are discussing in this
thread are exactly those edge/interop cases. You would never have an int or
Integer unless you asked for one or got one from some Java code. It doesn't
make sense to come into a discussion about interop, and say that we
shouldn't let interop determine the core of the language. This thread is not
about the language core.


> When doing an interop call, this is when you need to be specific. Elsewhere
> I see no value in keeping this scheme.
>

Exactly, we're assuming in this thread that we're already at the edge doing
interop, or trying to optimize our code. So any comments that assume we're
not doing interop are out of scope.

And with today's hardware, why stick with these data types ? To reduce
> memory footprint ?
> Ha ! Ha !, I used to work on computers with 256K of physical memory.
> This concern was legitimate in this prehistoric era. But today ?
>

There are good reasons at both ends of the computing spectrum to want to be
efficient with memory. Embbeded systems and mobile platforms don't
necessarily have terabytes of memory to access. And on the other end of the
spectrum at work, we process terabytes of data using byte arrays and byte
streams, if we all of a sudden needed 8 times the memory to do the same job,
it would probably be a deal killer.

Similarly, we have some native JNI libraries we use that limit us to using a
32-bit JVM on some of our nodes, and we are constantly fighting OOMEs in
those restricted heaps. Which is an interop case, which is the context of
this thread. The core of the language can use only longs, which is fine.


> If you need bit manipulation in Clojure, better write a lib for this than
> mangling with
> these data types.
>

I'd rather write that code in Clojure than Java and use it from Clojure (if
that's what you're saying). And if I'm dealing with data formats, (c.f. the
gloss library) it would be really inconvenient to always have things
converted to longs on me. I prefer to not have a language/platform that
thinks it knows what is better for me, than I do.


Paul

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

2011-10-23 Thread Paul Stadig
On Sat, Oct 22, 2011 at 5:51 PM, Stuart Halloway
wrote:

> I am dropping off this thread now.  At this point I think it would be more
> useful for me (or someone) to expand the notes about numerics into better
> documentation, rather than continuing this rambling point-by-point treatment
> without getting all of the considerations into play at once. I hope to get
> that done by conj.


So you are still thinking that the current behavior is OK and just needs to
be documented better? Or are you saying that we need to collect the various
pros and cons to decide whether the current behavior should change or remain
the same?

Having reviewed the thread there is lots of confusion, but from the points
made it seems clear to me that the behavior should change.

CON (The "we should box ints as Longs" (or "we should keep things as they
are") camp):
1) If we box ints as Integers it will break Clojure's collections (Stu
Halloway)
2) Boxing ints as Integers would make Clojure's design inconsistent (David
Nolen)
3) Clojure now only has 64-bit primitives (David Nolen/Kevin Downey)
4) If 32-bit ints are allowed to exist, the Clojure's numeric operators
would have to handle them (David Nolen)

CON1 is a bug in PersistentHashMap, and I opened a Jira bug for it (
http://dev.clojure.org/jira/browse/CLJ-861).
CON2 is false. The way primitives are boxed for interop doesn't and
shouldn't have any effect on Clojure's design as such. This is a discussion
about interop consistency, and if you look at the PRO section you will see
Clojure is already inconsistent with respect to interop. Nathan and others
are arguing that it should be made consistent.
CON3 is false. 32-bit primitives do exist in Clojure (at least Java
Clojure), they are just not the optimized case. They may get immediately
converted to longs or boxed in some way, but we cannot deny their existence,
especially around interop.
CON4 Again, 32-bit integers do exist, and are already handled by the numeric
operators. When you compile a function with primitive args, Clojure also
generates a method that takes Objects. If you pass in anything other than a
long it gets boxed, cast to a java.lang.Number, has its longValue method
called, and that value gets passed to the primitive arg version. This is
slow (as expected) because you are not using the optimized case (64-bit
primitives). Absolutely none of that would have to change/get slower because
ints were boxed as Integers instead of Longs.

I think the problem with all of these CONs is that they confuse boxing for
interop with either a bug in PersistentHashMap, or fast primitive maths, and
neither of those has anything to do with how ints are boxed.

PRO (The "we should box ints as Integers" camp):
1) Clojure is inconsistent in how it boxes primitive data (Chris Perkins)
Clojure 1.3:

(class (Long/parseLong "1"))  =>  java.lang.Long
(class (Integer/parseInt "1"))  =>  java.lang.Long
(class (Short/parseShort "1"))  =>  java.lang.Short
(class (Byte/parseByte "1"))  =>  java.lang.Byte
(class (Float/parseFloat "1"))  =>  java.lang.Float
(class (Double/parseDouble "1"))  =>  java.lang.Double


Paul

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

2011-10-23 Thread Paul Stadig
On Sat, Oct 22, 2011 at 7:53 PM, Luc Prefontaine <
lprefonta...@softaddicts.ca> wrote:

>
> Ha ! Ok, I missed the digression here and I now understand the issue.
> Considering that a PersistentArrayMap may eventually become a
> PersistentHashMap
> this opens the door to *funny* bugs.
>
> Is this the only known case ?
>

The bug in PersistentHashMap also infects PersistentHashSet. I've created a
Jira bug about it you can see the details there:

http://dev.clojure.org/jira/browse/CLJ-861


Paul

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

2011-10-22 Thread Paul Stadig
On Sat, Oct 22, 2011 at 5:42 PM, Luc Prefontaine <
lprefonta...@softaddicts.ca> wrote:

> What's missing from your shortened example ?
>

I think what you want is the example I posted originally:

user=> (get {(Long. -1) :here} (Integer. -1))
:here

That works fine because you are actually creating an PersistentArrayMap,
which does not care about hash codes. However, when you use a
PersistentHashMap you see were things break down because the hashing
function and the equality function that PersistentHashMap is using are not
congruent (i.e. they break the hashing contract):

user=> (get (clojure.lang.PersistentHashMap/create {(Long. -1) :here})
(Integer. -1))
nil
user=> (get (clojure.lang.PersistentHashMap/create {(Long. 0) :here})
(Integer. 0))
:here

This happens because PersistentHashMap does not use .equals to compare keys,
however it does use .hashCode to hash the keys. So it's fine to not use
.equals and define Clojurey semantics for integer comparisons, but if we're
not using .equals, then we should not be using .hashCode, and instead
redefine .hashCode with Clojurey semantics as well. The contract that is
being broken is the contract for hashing, not equality.

This problem has nothing to do with Java interop. I has nothing to do with
the Java language or the JVM. It has nothing to do with whether ints are
boxed as Integers or Longs. What is happening is PersistentHashMap is
supposed to be an implementation of an abstract Computer Science data
structure called a hash table, and for a hash table to work correctly the
following must be true: if two keys are equal, then their computed hash
values for those keys should be equal.

The reason we wandered into this is because one of the objections that has
been raised against boxing ints as Integers is that doing so would break
Clojure's collections. What I have been trying (unsuccessfully I gather) to
communicate is that PersistentHashMap is broken in and of itself, and boxing
ints as Longs only hides the issue. Boxing ints as Longs makes it less
likely that you would actually be using an Integer as a key, because you
have to explicitly ask for an Integer. However, if you explicitly ask for an
Integer you still get the broken behavior, because PersistentHashMap needs
to be fixed.

Bottom line: changing Clojure to box ints as Integers would not break
Clojure's collection, but Clojure's collections need to be fixed to use a
hashing function that is congruent with their equality function.


Paul

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

2011-10-22 Thread Paul Stadig
Luc,

On Sat, Oct 22, 2011 at 3:40 PM, Luc Prefontaine <
lprefonta...@softaddicts.ca> wrote:

> All the contracts you mention are language centric, each of them defined
> their contract according
> to their own needs. Clojure should have the right to do so.
>

The contract is required for implementing any kind of hash map anywhere.
This is not Java or the JVM influencing Clojure to do something it wouldn't
have otherwise. The references were examples to show that widely varied
languages/platforms agree: if you want to implement a hash map in any
language on any platform, then when two objects are equal their hashCodes
should be equal.

I'm fine with changing the Java semantics with respect to Integer and Long
equality, BUT if we're going to change equality, then the hashing function
has to be congruent with that equality function. If equals and hashCode are
not congruent, on any platform, in any language, anywhere, then you do not
have a hash map, you have a broken hash map. You can see the brokenness in
the example code I posted.


> Clojure prefers to avoid having different rules than Java regarding number
> handling ? Be so, it's legitimate.
>

I'm not arguing against that. I'm saying make the equality different, BUT
you also have to make the hashCode function congruent.

If people like you were free to take these decisions we would end up with
> three different languages, one on the
> jvm, one on CLR and one on JS. Nonsense. Having to deal with three
> different interops and trying to
> unify them a bit is enough work by itself.
>
> Interop stuff is low level and should remain there. If a single interop
> implementation starts to influence
> the Clojure language and result in such short term and narrow scope
> decisions, we will all have a problem
> in the future.
>

I mean, again, I don't understand why you're saying this. I agree interop
needs to exist and to be at a low level. The question is, given that some
form of interop must exist, how should it work? Right. The discussion that
we're having here is about how Java interop should work. I don't think it
makes sense to come in and say, that we can't let Java and the JVM influence
how we interop with Java and the JVM. Perhaps you are misunderstanding me,
or I you.

I'm saying given that there must be some form of interop, it does not make
sense to box ints as Longs. And the decision to box them as Integers instead
should not have any effect on the semantics of anything. Two objections have
been raised against boxing ints as Integers so far: 1) it breaks Clojure's
collections, and 2) it would have bad effects on the new faster primitive
maths.

I'm saying: 1) Clojure's PersistentHashMap is broken because it is using
incongruent equals and hashCode methods, auto-promoting ints to Longs only
hides this, and if you explicitly create an Integer (or get one from Java)
PersistentHashMap will still behave badly. Promoting ints to Longs only
masks the issue.

2) autoboxing ints to Integers would not have any bad effects on the new
faster primitive maths.

And as a third point, ints being boxed to Longs stands out as inconsistent
with the way all the other primitive integer types are handled.


Paul

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

2011-10-22 Thread Paul Stadig
On Sat, Oct 22, 2011 at 1:49 PM, Luc Prefontaine <
lprefonta...@softaddicts.ca> wrote:

>
> Java != JVM.
>
> That's a too common mistake. Integer vs Long, Byte, ... are Java creations.
> They have nothing to do with the JVM primitive data types.
>
> Clojure implements a semantic different than Java on top of the JVM, why
> not ?
> That's the whole idea of having the JVM around. Abstracting the metal.
>
> Clojure reuses Java strings as is but it could have implemented its own on
> top of the
> char primitive type at the expense of less transparent interop. This is an
> implementation choice.
> It does not tie Clojure to Java.
>

Um...I guess I don't understand how what you're saying is relevant. Are you
saying that Clojure should implement it's own Byte, Short, Integer, and
Long? If you are, then the hashCode contract should be obeyed. If you're
not, then it's fine for PersistentHashMap to redefine equals for
java.lang.{Byte,Short,Integer,Long}, but hashCode should also be redefined.

The hashCode contract is not a Java thing, it is a JVM thing, and in fact
(as I mentioned before) it is a mathematical contract that you must obey to
implement a hash table in any language and on any platform.

Python has a similar contract
http://docs.python.org/reference/datamodel.html#object.__hash__

C# has a similar contract
http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx

Common Lisp has a similar contract
http://www.lispworks.com/documentation/HyperSpec/Body/f_sxhash.htm#sxhash

The brokenness of PersistentHashMap with respect to the hashCode problem has
nothing to do with Java (or even the JVM).


> These are Clojure centric decisions. Lets get out Java out of this
> discussion.
> Clojure is not Java and even if it provides a "soft" bridge
> to reuse Java code, its feature set is certainly not Java centric.
>
> A Clojure persistent map is a ... Clojure data structure, not a Java data
> structure.
> Interfaces like java.util.Map have nothing to do with the content of the
> map itself.
> If they help make interop calls smoother fine. But do not tie their Java
> semantic to
> the Clojure semantic. It's unrelated outside of the interop domain.
>

> I do not care about Java centric stuff. I adopted Clojure to get away from
> Java
> ASAP.
>

The reality is that PersistentHashMap does implement j.u.Map, and as much as
possible Clojure tries to live at peace with other classes/objects on the
JVM. There will always be some level of interop and semantics that must be
matched with the platform. If you want to totally avoid Java, then I don't
think Clojure is going to help you. It's not just a coincidence that Clojure
strings are java.lang.Strings, and there are probably many people who would
not have found Clojure as compelling if it didn't have a great interop
story, and the ability to access a huge set of existing libraries. I feel
like this is drifting off topic though.

Coming back to the original issues:

1) PersistentHashMap should be using a hashing function that is congruent
with the equals function it uses.

2) Boxing ints as Longs sticks out when every other primitive is boxed into
its java.lang.* equivalent.

3) Boxing ints as Integers would not have any adverse effect on the
improvements to primitive maths.

I'd be glad to help out with any of this.


Paul

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

2011-10-22 Thread Paul Stadig
On Sat, Oct 22, 2011 at 9:48 AM, Chas Emerick  wrote:

> If Clojure's primary objective were Java interop, I might agree with you.
>  However, it's not, and it's bizarre to see someone argue that this is not
> broken:
>
> user=> (.equals (Integer. -1) (Long. -1))
> false
>
> Sure, not broken according to the Java object model and its equality
> semantics, but damn well broken if your standard is something other than
> what was canonized in java.lang.Object 20 years ago.  1 == 1 all the time —
> or, it should — regardless of the containers such integers incidentally find
> themselves within.
>

>From the beginning Clojure's story has been, "why reinvent the wheel when
there's this great JVM with a million man-months of engineering," and I do
believe interop has been a huge objective. There are lots of existing
libraries that can be used, and the whole "Clojure integers are
java.lang.Integers, and Clojure Strings are java.lang.Strings" always seemed
to me to be about interop and being a good, integrated citizen on the JVM.

Of course I was not saying that 1 should not equal 1. I was saying that to
be on the JVM you should adhere to the hashCode contract. And it's not the
java.lang.Object equality semantics that are broken. The hashCode contract
is a mathematical contract that you must follow if you want to implement a
hash table in any language. Sure, Integer and Long seem to be weird in that
they are not equal to each other when they are in the same range, but that's
a problem with Integer and Long semantics, not java.lang.Object semantics.
And you can't fix that problem by essentially rewriting/overriding the
equals method for Integer and Long, and not also rewriting/overriding the
hashCode method for those same classes. If you don't also override hashCode,
then you get broken behavior as I demonstrated.

Thus, Clojure's notion of equivalence, which leads to pleasantly consistent
> behaviour, e.g. (== (Integer. 1) 1 1N). Which, of course, doesn't preclude
> one using .equals if you truly want Java math semantics instead of = or ==
> (neither of which have ever been advertised as adhering to the
> hashcode/.equals contract, at least since Clojure 1.0 IIRC).
>

Clojure PersistentHashMaps are java.util.Maps, and to whatever extend
Clojure defines new types on the JVM and implements an equals method for
those types, it should also implement a hashCode method that adheres to the
contract.


> If there are some common rough spots in the interop for certain use cases,
> perhaps those can be smoothed out with a library, maybe contributed by
> someone that acutely feels that pain.
>

I don't intend to muddle the discussion, but only to point out that there
are two separate issues:

1) the way collections behave when you use Longs that are in the Integer
range. This is a problem with the implementation of PersistentHashMap, and
unrelated to boxing ints as Longs. Boxing ints as Longs only hides the
underlying issue that PersistentHashMap should not be using the default
implementation of hashCode, but it's own implementation of equals.

2) ints being boxed as Longs. When you looks a Chris Perkin's post it
certainly seems broken that ints are the *only* primitive that is not boxed
into its java.lang equivalent. Also, AFAICT boxing ints as Integers would
have no effect on the faster numeric maths.


Paul

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

2011-10-22 Thread Paul Stadig
On Wednesday, October 19, 2011 10:38:56 AM UTC-4, stuart@gmail.com 
wrote:
>Integers and longs are going to be painful no matter what because they are 
broken in Java, e.g.

It is incorrect to say that "Integers and longs...are broken in Java."

user=> (.hashCode (Integer. -1))
-1
user=> (.hashCode (Long. -1))
0
user=> (.equals (Integer. -1) (Long. -1))
false

This is consistent with the contract for hashCode. Java would be broken only 
if equals returned true, but the hashCodes were different. If anything 
Clojure was (and in fact still is) broken, since Clojure makes Long and 
Integers in the same range equal, but does not make their hashCodes equal:

user=> (hash (Integer. -1))
-1
user=> (hash (Long. -1))
0
user=> (= (Integer. -1) (Long. -1))
true

Henceforth referred to as "the hashCode problem".

On Thursday, October 20, 2011 9:00:23 AM UTC-4, stuart@gmail.com wrote:
>Somebody has to work hard: either users of collections, or interop callers. 
The current behavior makes things "just work" for collections, at the cost 
of having to be explicit for some interop scenarios.
>
>There are two reasons to favor collection users over interop users:
>
>   (1) Interop problems are local, and can be resolved by checking the type 
signature at the point of the problem. Collection key problems are global 
and break the composability of collections. It is a *huge* benefit of 
Clojure that collections are sane.

Munging the data as it goes into a collection does not fix the hashCode 
problem.

PersistentArrayMaps don't have the hashCode problem, because they don't 
actually bother with hashCodes:

user=> (get {(Long. -1) :here} (Integer. -1))
:here

But boxing ints as Long doesn't actually fix the hashCode problem for 
PersistentHashMaps.  Big 'I' Integers still hash differently than big 'L' 
Longs, yet Clojure considers Longs in the Integer range to be equal to 
Integers, and this is the fundamental problem with Clojure's collections. 
E.g.

user=> (get (clojure.lang.PersistentHashMap/create {(Long. -1) :here}) 
(Integer. -1))
nil
user=> (get (clojure.lang.PersistentHashMap/create {(Long. 0) :here}) 
(Integer. 0))
:here

Since Clojure isn't making the hashCodes for Integers and Longs the same, 
the collection experience is still broken.  One could say, "Yes, Paul, but 
it is less broken now, because you will only see this issue if you 
explicitly create a big 'I' Integer."

Then I could say, "Yes, One, that may be true, but in that case presumably I 
have a reason to explicitly ask for a big 'I' Integer, and I should 
understand the implications. Similarly, I probably have a reason for asking 
for a little 'i' int.  Clojure may think it knows best by boxing ints as 
Longs, but I'm pretty sure I know what's best in this particular situation 
in my code."

Then One could say, "But using only longs makes math much faster, and makes 
the collection experience more consistent."

Then I could say, "One, you are complecting two different issues. Making 
Clojure literals always longs is fine, it's great.  Making the Clojure 
compiler generate fast code for little 'l' longs is great. That means that 
you should only run into this collection brokenness if you are explicitly 
asking for and creating big 'I' Integers. However, the collection experience 
not being consistent is a problem with the collection implementation.  
PersistentHashMap should not be using Integer's hashCode method if it is not 
using Integer's equals method."

>   (2) There are a lot more lines of code working with collections than 
doing interop.

I think the issue with interop is that I am explicitly asking for ints 
and/or Integers, and when I'm doing interop I expect that Java semantics be 
preserved, which means that ints get boxed into Integers.  I don't believe 
that boxing ints as Integers should harm any of the primitive math 
enhancements, nor would it harm the concept of Clojure "as a language unto 
itself" having only 64-bit math.  Those are orthogonal issues.


Paul

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

Re: [ANN] Clojure 1.3 RC0

2011-09-14 Thread Paul Stadig
Yeah it makes sense and is vaguely familiar now. I should have read the 
changelog. In our case we have a with-channel macro that expands into a try 
that I think could be moved up to a higher level and not be recuring across 
a try.


Thanks,
Paul

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

Re: [ANN] Clojure 1.3 RC0

2011-09-14 Thread Paul Stadig
For unsupported behavior it seemed to work pretty well in our code :), but 
perhaps it was just a timebomb. In our case it was several layers of macros 
obscuring the recur across try.

I guess we'll have to figure out how to rewrite around it, when we get 
around to picking up 1.3.


Paul

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

Re: [ANN] Clojure 1.3 RC0

2011-09-14 Thread Paul Stadig
This compiles fine in 1.2.1, but fails in 1.3.0-RC0

(defn foo [[bar & baz]]
  (try
(if (seq baz)
  (if (= bar 99)
(throw (Exception. "FAIL"))
(recur baz))
  bar)
(catch Exception e
  :fail)))

You get a compiler error: java.lang.UnsupportedOperationException: Cannot 
recur across try

I assume there is a reason for this? Or should it be considered a bug?


Paul

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

2011-09-06 Thread Paul Stadig
I started on some work to use invokedynamic instructions (instead of
reflection) for calling Java interop. I based my work on 1.3beta2, and my
goal was just to see how much of a performance difference it could make (if
any).

So far all I have done is update the bundled ASM and modify Clojure to emit
Java7 class files, but I'm getting VerifyErrors (same as Tal). It's possible
that this is a bug in the way that ASM automatically calculates stack maps,
or perhaps it is the best that ASM can do, in which case the Clojure
compiler would have to be modified to do bookkeeping around stack maps.

I even tried moving to ASM trunk to see if it made any difference, but it
didn't.

Anyway, I pushed a couple of branches to my fork of Clojure:

https://github.com/pjstadig/clojure/tree/indy-3.3.2

and

https://github.com/pjstadig/clojure/tree/indy-trunk

Perhaps when ASM 4.0 is finalized it will be a different story.


Paul

On Mon, Aug 29, 2011 at 7:05 PM, Tal Liron  wrote:

>  On 08/29/2011 06:01 PM, Aaron Bedra wrote:
>
> The version of ASM that is bundled in Clojure is very old.  This will
> likely cause problems.  You are correct in looking to ASM 4 since it has
> started supported the JSR-292 stuff and other Java 7 changes.  I am
> planning on doing an extraction, update, and re-packaging of ASM in
> Clojure as soon as Programming Clojure hits the printers.  This most
> likely won't get started until October though because of conferences.
>
>  I've already done that for my branch (that was a task in itself! needed a
> little monkeypatching to support Clojure's DynamicClassLoader), so you may
> want to leave it to me.
>
> My code is in quite a messy state now and I'm embarrassed to make it public
> quite yet...
>
> BTW, does somebody have an Eclipse Java code formatter configuration for
> Clojure's wacky coding style?
>
> -Tal
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from 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: JVM 7 support (invokedynamic)

2011-08-28 Thread Paul Stadig
On Sun, Aug 28, 2011 at 10:58 AM, Tal Liron  wrote:

> I wonder if it would be that difficult to replace the reflector code with
>> an invokedynamic. There is a way to get from a java.lang.reflect.Method to a
>> java.lang.invoke.MethodHandle (see
>> java.lang.invoke.MethodHandles.Lookup.unreflect). You could probably just
>> replace the code that emits a direct call to clojure.lang.Reflector to emit
>> an invokedynamic instruction that calls a bootstrap method that wraps the
>> Reflector code and just converts the Method into a MethodHandle for
>> bootstrapping.
>>
>
> I think you're overstating the problem: reflection is ugly, but it only
> happens here during compilation. From then on, the compiled code does what
> it needs to do with the types. At least, that's my reading of it: you told
> me before that I was dead wrong here, and maybe I am! If I'm right, then I
> don't see a "gap" here that invokedynamic can help bridge.
>

If you look at the links in my previous e-mail (specifically this one
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L1364).
The reflection is done in the compiler only when there is a tag (i.e. a type
hint). Otherwise the compiler just emits an invoke instruction to call the
Reflector at runtime. That invoke could be replaced with an invokedynamic
instruction.

If you are able to push a branch I may be able to find some time to hack on
it.

Thanks for sticking with this though. The more I understand about
invokedynamic the more interesting it becomes.


Paul

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

2011-08-28 Thread Paul Stadig
On Sun, Aug 28, 2011 at 10:25 AM, Tal Liron  wrote:

> Progress!
>
> I am staring right now at my JVM 7 build of Clojure that uses invokedynamic
> for Vars that contain functions. It essentially works, well enough for
> experimentation. A few of my simple apps seem to work fine with it.
>
> There are still a lot of problems: the Clojure test suite fails, and my
> re-linking fallback mechanism (based on SwitchPoint) does not differentiate
> between root bindings of Var and their "box" thread-binding, so in theory
> any rebinding will cause all linkages on that Var to reset. Not very
> optimal.
>
> I've really done very little optimizing at all at this point: invokedynamic
> is just replacing the usual invokeinterface. So, I was surprised that when
> fooling around with some benchmarks, one of them showed about 30%
> performance improvement on one of my Clojure-built web servers. Tantalizing!
> But, until the test suite succeeds, I can't be sure that this isn't a side
> effect of something not so great that's going on.
>
> I'm hoping to have something the rest of you can play with soon, but
> thought you would want to hear a progress report. What would be the most
> convenient way to share this? A dump to github of the whole tree? A patch?
>

Hey that's good news! It would be simple enough for you to push a branch to
your own fork of Clojure on github.


> I've used the Clojure 1.2.1 codebase, because I didn't want to work on a
> moving target, and also think it might be easier for the community to help
> test this with existing applications. (As I said earlier, I also have a few
> ideas on how to make sure we can have this mechanism gracefully downgrade to
> JVM <7.)
>
> Many thanks to Paul Stadig and Charlie Nutter for prodding me to realize
> that the one point where invokedynamic can help is to bridge the gap between
> dereferencing the Var and then calling invokeinterface on it. My mistake
> when looking at this the first time around was assuming that the
> dereferencing and subsequent invokeinterface were fast operations, and that
> it would make little difference to replace them with invokedynamic. But,
> speed is not the issue here: it's that this gap represents a black hole for
> HotSpot, around which it can't optimize well. Because this mechanism
> represents the primary junction for all of Clojure, optimization here could
> enable some nifty optimization across the board. I think it's a good way to
> imagine invokedynamic's benefits: it's a bridge over troubled water for
> HotSpot.
>
> Paul also points out areas where MethodHandles can replace the rather
> sticky reflection work that Clojure does now to massage calls to non-Clojure
> libraries. That's not entirely related to the invokedynamic stuff I'm
> working on, so I think I'll leave it to somebody else to take a stab at
> that...
>

I wonder if it would be that difficult to replace the reflector code with an
invokedynamic. There is a way to get from a java.lang.reflect.Method to a
java.lang.invoke.MethodHandle (see
java.lang.invoke.MethodHandles.Lookup.unreflect). You could probably just
replace the code that emits a direct call to clojure.lang.Reflector to emit
an invokedynamic instruction that calls a bootstrap method that wraps the
Reflector code and just converts the Method into a MethodHandle for
bootstrapping.

But things always seem easier until you actually get into them. :)

Paul

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

2011-08-28 Thread Paul Stadig
On Sat, Aug 27, 2011 at 8:31 PM, Tal Liron  wrote:

> I can think of a few ways in which it would be possible to distribute a
> clojure.jar that supports JVM 7 features while still falling back to JVM 5
> compatibility. So, I don't think this was ever a barrier. But you obviously
> unconvinced by my report! Thank you for challenging me on this, As I said,
> I'm by no means 100% sure I exhausted the issue. I would encourage you to
> try out your ideas.
>

I agree. I wasn't saying that it was impossible to target both Java 5 and
take advantage of Java 7 features. I had mentioned that targeting Java 7
could be specified as an option when AOT compiling, or it could
automatically be detected when compiling at runtime. However, I think that
people (perhaps rightly so) make the argument that the amount of effort
weighed against compatibility concerns and resource allocation and the
percentage of Clojure code that would benefit, doesn't make it worth doing.
That's different than saying that there would be no benefit to Clojure.

*-- If you don't provide any type hints, then the constructor for
> InstanceMethodExpr sets method = null and warns you that you're doing
> reflection...[snip]
> *
> You are right! This is perhaps the only place where invokedynamic can be
> useful for Clojure. *However*, to me this is not a big deal, because the
> workaround of allowing for type hinting solves the problem just as well, and
> perhaps even more efficiently from the compiler's point of view. All it does
> is require some extra annotations by the programmer. The fact that Clojure
> emits a warning seems good enough for me, personally.
>

This seems to be a standard response from people, and I don't really
understand it. You are comparing apples to oranges. Don't get me wrong. Type
hints are a critical tool for improving the performance of critical
sections, and would probably be necessary even if Clojure's dynamic dispatch
was faster than it is, but it seems like a win to just automatically make
dispatch faster without type hints, and I guess it boils down to mostly
non-technical factors (see above). Plus the biggest boost would be to code
that interoperates with Java, which is arguably rarer than pure Clojure code
(though I think that invokedynamic could even speed up Var dispatch,
protocol dispatch, and multimethod dispatch (see below)).

*-- I may be missing something, but I don't see how JRuby needs different
> classes.*
>
> But there is in fact another serious limitation of the JVM that comes into
> play here, which might seem very obvious to [Charles Nutter] but not so much
> to Clojure folk: the smallest container unit of code for the JVM is a class.
> There is no such thing as a free-floating procedure that you can just invoke
> whenever. ...
>
> ...This is a problem not only for JRuby, but also for implementing
> delegates in the Java, a long-request feature. Java thus needs to do
> ridiculous things like this, which in C# (for example) would be done so much
> more elegantly:
>
> new Thread(new Runnable() { public void run() { ThisIsMyFakeDelegate();
> }).start();
>
> What we did above was create a new (anonymous) class as well as an
> instance! Clojure does essentially the same thing per fn, extending AFn
> instead of implementing Runnable.
>
> * Correction: In my original report, I said that Clojure creates only
> instances of AFn, not classes. I was misstating the situation: it's exactly
> one class and one instance per fn. Clojure extends AFn and simply overrides
> the correct method according to arity. ...
>

I'm still not seeing an problems that are different than Clojure. JRuby must
create a class for every method of every class in order to make the methods
hot-swappable at runtime. Clojure does the same thing for its IFns and for
the same reason. Both JRuby and Clojure would have to do this even if
invokedynamic didn't exist, because it is a problem more with classes and
class loading, than with invocation. I don't necessarily want to get
distracted by this...

*-- Clojure has similar needs. For instance, Clojure has protocol dispatch
> and multimethod dispatch as well as Var based dispatch. The multimethod
> dispatch does a look up in the derivation hierarchy. All of this stuff can
> change at runtime, just like in Ruby you can add methods to a class, change
> methods on a class, etc. I don't see how Clojure's dispatch needs are much
> different than what other dynamic languages are doing.
> *
> So, perhaps I'm not understanding how you are using the term "change at
> runtime" to describe both JRuby regular dispatch and Clojure's multimethod.
> ...
>

Correct me if I'm wrong, but multimethod dispatch calls a dispatch function
that returns a value. This value can then be used to inspect the global
derivation hierarchy. Then the result is used to find the right defmethod to
call, by basically looking up in a dictionary of methods. The global
derivation hierarchy can be changed at runtime which can cause differe

Re: JVM 7 support (invokedynamic)

2011-08-26 Thread Paul Stadig
On Thu, Aug 25, 2011 at 6:05 PM, Tal Liron  wrote:

>
> Hmm... If you didn't have to worry about Java <7 compatibility, for one
>> thing with invokedynamic you could remove a lot of code from Clojure. No
>> more IFn or AFn. You simply have a method handle.
>>
>
> Actually, Clojure's solution is almost identical to a method handle. An
> instance of AFn is not much different from an instance of MethodHandle, from
> the JVM's standpoint. The problem MethodHandle solves for languages like
> JRuby is that they need *different classes* for each method handling,
> whereas Clojure gets away with instances. Where using MethodHandle becomes
> important is when you want to participate in the invokedynamic
> bootstrapping, which expects MethodHandle instances. If Clojure ever needs
> to do this, it would be a simple one-to-one translation from AFn.
>

I may be missing something, but I don't see how JRuby needs different
classes. If you look at the JRuby code at the most basic level a method on a
class is an instance of org.jruby.internal.runtime.methods.* or something
else and those classes don't have so much to do with dispatch styles as
optimizations. See, JRuby is able to achieve performance that is pretty darn
close to Java, while still doing dynamic dispatch (without type hints).
Clojure can not even get close to Java performance without type hints. All
those different Method classes and all the complex stuff that JRuby does to
make *dynamic* dispatch fast now gets pushed down into the JVM, and if
Clojure taps into it, we could also get performance for dynamic dispatch
that is much closer to Java.

One could say, "If you want performance use type hints," and that's a valid
opinion, but again it's a different thing. Using type hints you are
switching to static dispatch. If you want much better performance for
*dynamic* dispatch, if you want much better performance without having to do
type hints, then invokedynamic is here to help.

Also, there's actually a huge difference between IFn and MethodHandle. When
you invoke an IFn you have to cast your arguments into Objects, which for
primitives means you have to box them. When you invoke a MethodHandle, this
does not happen. You push your primitive arguments onto the stack, then when
the invokedynamic instruction is executed the arguments are boxed only if
necessary. Same thing with casting objects. You push the raw arguments onto
the stack, and at runtime you can do casts, if necessary. IFn is a static,
compile-time interface, and when using it you must force your arguments into
it's compile-time signature. MethodHandles are not compile-time.

Second, I think it would allow the JVM to have a better view into
>> optimization, and would allow the JVM to optimize something speculatively
>> and allow for Clojure tell the JVM when to deoptimize with a SwitchPoints
>> and MutableCallSites.
>>
>
> Except that there's no functional mutability in Clojure! I tried hard, but
> I could not come up with a case in which this could be used. What are you
> thinking of, specifically?
>

A function value is immutable in Clojure, but Vars are not. Protocols are
not. Multimethods are not. Those are the cases I'm thinking of where you
could use SwitchPoints to tell the JVM, "hey, I know you optimized this
MethodHandle by inlining all the code, but now the Var has changed (sorry)."


Paul

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

2011-08-26 Thread Paul Stadig
On Thu, Aug 25, 2011 at 5:41 PM, Tal Liron  wrote:

> So, after setting up a JVM 7 environment to play with Clojure, and
> enthusiastically rummaging through the codebase, I have good news and bad
> news. :)
>
> So, when Clojure calls a function, it either already has the instance in
> its entirety (a lambda) or it finds it by dereferencing a binding. Since all
> functions are instances that implement IFn, the implementation can then call
> invokeinterface, which is very efficient.
>
> [See clojure.lang.Compiler#InvokeExpr.emitArgsAndCall]
>

What I said in another post was that with invokedynamic (assuming you could
just go whole hog into Java 7) you don't need the IFn interface. You just
need a MethodHandle. So yes, I agree that given all the existing Clojure
code, and the desire to stay compatible with Java 5 or 6 or whatever,
invokedynamic isn't very compelling. If you were going to do a green field
project, and didn't mind the Java 7 requirement, invokedynamic is very
compelling, because you can basically push a bunch of code down into the
JVM. This mean much less work, and it means you get to benefit from any
improvements and optimizations that get built into the JVM. Even for Clojure
having an optional Java 7 target may still be interesting in that it allows
you to hook into all the work that will be done on invokedynamic to support
the whole dynamic language ecosystem on the JVM.


> Clojure can get away with this especially easily because the only variant
> for function signatures in Clojure is arity. So, all we need is a simple
> switch to call the IFn method with the correct arity. (Interestingly, this
> means that Clojure has a fixed set of such signatures, and thus a fixed
> upper limit to arity: 20, in case you were wondering.)
>
> In a language like Ruby, methods are not so free floating, and have much
> more complex invocation styles as well as flexible signatures. (Clojure has
> only one style: function calls are simple forms.) So, in order to use
> invokeinterface, JRuby implementors would have had to create special classes
> *per* method *per* invocation style if they wanted to be efficient. But this
> is impossible, because so many classes would exhaust the perm-gen. For those
> languages, invokedynamic is a terrific solution, because it lets them
> dynamically link the implementation to the caller via a flexible
> "bootstrapping" mechanism, allowing them to do entirely without the extra
> class definition. Since all Clojure functions share essentially the same
> class as well as interface, none of these challenges exist.
>

It's very possible that I'm missing something, but I'm not quite sure what
you're getting at here. In JRuby, for instance, the method overloading is
the same as in Clojure, it is based on arity. The slowdown is in dispatch
where you have to check a singleton class, your class, your ancestors, then
method_missing, etc. Once you've looked this all up you cache it to speed it
up later. Then you want to invalidate the cache when the world changes.

Clojure has similar needs. For instance, Clojure has protocol dispatch and
multimethod dispatch as well as Var based dispatch. The multimethod dispatch
does a look up in the derivation hierarchy. All of this stuff can change at
runtime, just like in Ruby you can add methods to a class, change methods on
a class, etc. I don't see how Clojure's dispatch needs are much different
than what other dynamic languages are doing.


> Another aspect is the immutability of these IFn instances: you can't
> refactor them at runtime, all you can do is change the bindings to refer to
> new functions. So, Clojure achieves runtime dynamics by letting you simply
> rebind new functions to existing Vars, Refs, Atoms, etc., and the same
> invocation route continues as usual. In a language like Ruby, the
> bootstrapping mechanism of invokedynamic lets implementors change the base
> linkage to reflect a new signature for the method. Again, a terrific JVM 7
> feature that Clojure simply does not need.
>

The "signature" of a JRuby method is not much different than a Clojure
method. It is an arity overloaded method with generic arguments. They do
similar things to lots of other dynamic languages (including Clojure) like
generating a class with a bunch of different versions of the same method
with different numbers of generic arguments (
http://jruby.org/git?p=jruby.git;a=blob;f=src/org/jruby/internal/runtime/methods/DynamicMethod.java;h=b65854c057c8a1acec57d6dad95158f08c960dcc;hb=HEAD#l203).
invokedynamic isn't about method signatures it's about dynamic dispatch,
which is what Clojure does.


> Another issue I examined was how Clojure calls non-Clojure JVM code,
> thinking that perhaps there invokedynamic would be useful. But, Clojure
> again has a straightforward approach that poses no problems. Here, Clojure
> very directly calls non-Clojure code using invokestatic, invokevirtual or
> invokeinterface as appropriate. A Clojure form with the "." or ".

Re: JVM 7 support (invokedynamic)

2011-08-25 Thread Paul Stadig
Right invokedynamic doesn't just "mostly benefit object-oriented languages." 
A MethodHandle can be used for anything that the JVM can do from a static 
method call, to an instance method call, to a constructor, to a field 
access.

And in fact the bootstrap method that links an invokedynamic call site does 
not have to dispatch on the type of the first argument in an object oriented 
way, it can actually do completely generic dispatch akin to Clojure's 
multimethods.

You can take a MethodHandle and curry the method by supplying some of the 
arguments, and this nice little packaged MethodHandle is given to the JVM 
with complete transparency for it to do it's stuff.

You can create collector and spreader methods to do things like RestFn does 
where it takes rest args. You could probably even do destructuring of 
arguments in a chain of MethodHandles that the JVM then could understand and 
optimize.

Maybe not all that potential is fully delivered with the current release of 
Java 7, but I think the transparency that invokedynamic allows should make 
it much easier for the JVM to do better optimizations.


Paul

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

2011-08-25 Thread Paul Stadig
Hmm... If you didn't have to worry about Java <7 compatibility, for one 
thing with invokedynamic you could remove a lot of code from Clojure. No 
more IFn or AFn. You simply have a method handle.

Second, I think it would allow the JVM to have a better view into 
optimization, and would allow the JVM to optimize something speculatively 
and allow for Clojure tell the JVM when to deoptimize with a SwitchPoints 
and MutableCallSites.

I don't think Phil's comparison is actually a fair one. If you're going to 
use type hints or type inference, then you're basically moving more towards 
static typing, which of course will be faster.

If you're going to do dynamic dispatch without compile time types to aid the 
compiler, then invokedynamic is most certainly going to be faster than 
reflection, and make for much simpler code.

I think invokedynamic would be great for Clojure. Of course there are other 
concerns like the fact that it is only for Java 7, so maybe it won't be the 
best place to put resources at the moment. But that's no reason that Tal 
can't work on it.


Paul

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

Michael Fogus will talk about ClojureScript tomorrow night (8/25)

2011-08-24 Thread Paul Stadig
If you're in the Washington DC area, and are interested in hearing about 
ClojureScript from Fogus, he'll be presenting at the CAPCLUG meeting 
tomorrow night http://www.meetup.com/Cap-Clug/events/16237174/.

I believe his talk will be something about the compilation of ClojureScript 
to JavaScript, but maybe he can jump in and give details.

See you there!


Paul

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

2011-06-22 Thread Paul Stadig
On Jun 19, 5:11 pm, Andreas Liljeqvist  wrote:
> Thanks for the answer.
> Would there be any problems associated with changing the root bindings?
>

It means that every thread in the whole JVM would get that value, but
that's probably what you want. It also means that if someone else
changed the root value to a different value, all the threads would get
that new value, instead of the one you want.

In the case of this particular var none of this may be an issue.


Paul

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 Paul Stadig
I've rarely found these coding style discussions to be productive, and have
wondered why source control systems don't just store code in a whitespace
normalized format and automatically format the code to your own taste when
you check it out, because, let's face it, formatting is semantically
irrelevant. It may help *you* grasp the meaning more quickly, but the
opposite may be true for others. But I guess automatic formatting would
totally destroy the ability to talk about line 16 of a particular file.

Then I move on to thinking it best for a language designer to just legislate
fomatting and make it a compiler error, but that would probably generate
more discussion than otherwise, so I've just written the whole thing off as
a lose-lose situation. But maybe I'm just getting cumudgenly in my old age.

I do however firmly believe that each language has a worldview and a culture
that coaleces around it, and one is better off either adopting it whole hog,
or finding another language that matches better with one's own worldview.
Something akin to what Brenton said about choosing a language because it
mirrors your thinking, not because of readability concerns. It is a disaster
to try to force the idioms of one language to be true in another.

Paul

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

2010-08-05 Thread Paul Stadig
I believe the code already does what you are asking about.

Are you talking about something like this?
http://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/APersistentMap.java#L57

this?
http://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/APersistentSet.java#L58

and this?
http://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/APersistentVector.java#L45

Or am I misunderstanding the OP?


Paul

http://paul.stadig.name/ (blog)
703-634-9339 (mobile)
pjstadig (twitter)
p...@stadig.name (jabber)

Projects
http://www.mycrossoverpoint.com/
http://www.reformedchurches.info/


On Thu, Aug 5, 2010 at 8:38 AM, Nicolas Oury  wrote:

> Just a quick follow-up.
>
> This is a big plus when you know (from meta reasons) that most
> successful equality tests will come from the identical? part of the
> test.
> Then you have most of the fail in O(1) by hashing and most of the
> successes in O(1) with identical?. While still being correct and
> complete.
>
> What I have in mind is one of my recurring rant about Hash Consing.
>
> http://en.wikipedia.org/wiki/Hash_consing
>
> With a clever caching of hash value and comparing the hash, you can
> have an equality for records that is O(1) with high expectation on any
> hash-consed values,
> while still being correct for non hash-consed value.
>
> Best,
>
> Nicolas.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from 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: terracotta?

2010-07-21 Thread Paul Stadig
There are agents, atoms, vars, seqs, and lisp macros all of which may make
Clojure a more appealing alternative to Java for use with Terracotta.

My goal was to get Clojure working with Terracotta, period. Most of the work
I did was actually focused on vars so that you could define a function and
have it available throughout the cluster, but eventually I did want to see
the STM working in Terracotta. Performance doesn't always matter all the
time for every problem, but its good to keep in mind what you are saying
when making decisions where performance does matter.

On Jul 20, 2010 8:46 PM, "peter veentjer"  wrote:

Hi Chas,

if you want to 'spawn' independent processes over different machines,
terracotta could be an option. But as soon as these processes are
going to share state, it gets a lot more complicated since a scalar
clock MVCC based stm is not going to be scalable over different
machines.

Afaik the focus of Paul was on distributing the Clojure STM using
terracotta.


On Jul 20, 5:47 am, Chas Emerick  wrote:
> I can't respond to that, but pres...
> >>> is athttp://github.com/pjstadig/tim-clojure-1.0.0andittries to be

> >>> a Clojure
> >>> 1.0.0 compatible TIM, which shows how its a bit out-of-date.
>
> >>> I am very...

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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-18 Thread Paul Stadig
I think what you are doing is analogous to the peek and pop operations in
core.

To get and remove and item you would peek to get the first item, and then
alter your ref with a pop, which returns the structure minus with the first
item removed.

If you do all of this within a dosync, including the peek, then if the
transaction is retried you'll get the new first value, and everything will
remain consistent.

Paul

On Jul 17, 2010 6:20 PM, "Peter Schuller" 
wrote:

Another thing occurred to me: While not necessarily important in the
cache of an LRU cache, one might want a data structure, even if it
tends to be used in a side-effectful manner, to participate in STM
co-ordinated transactions. If one hides an underlying ref, this means
that either callers do not have full control (to do, for example,
(ensure ..) on the ref), or the interface needs to provide specific
features to support this (e.g., lru-ensure).

Again, for an LRU cache I think this may be a far-fetched desire to
have and so it is probably not an issue. Maybe there are other data
structures though, with a similar inappropriateness for a functional
interface, where full participation as a persistent data structure
with respect to STM would be desirable.


-- 
/ Peter Schuller

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

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

2010-07-15 Thread Paul Stadig
If anyone is interested, the latest version of my terracotta TIM is at
http://github.com/pjstadig/tim-clojure-1.0.0 and it tries to be a Clojure
1.0.0 compatible TIM, which shows how its a bit out-of-date.

I am very open to collaboration, and I would love pull requests, or any
patches that anyone sends.


Paul

http://paul.stadig.name/ (blog)
703-634-9339 (mobile)
pjstadig (twitter)
p...@stadig.name (jabber)

On Thu, Jul 15, 2010 at 12:35 PM, scx  wrote:

> Hi --
>
> I'm noob to both Clojure and Terracotta but if you're willing to
> tolerate basic questions from me, I'd be very interested in helping
> out.
>
>
> On Jul 12, 3:36 am, peter veentjer  wrote:
> > I don't think it every is going to scale.
> >
> > MVCC/TL2 based STM designs rely on a central clock, so if you can
> > update the clock in 0.1 ms on all machines, the maximum throughput is
> > 1/0.0001 = 10.000 transactions/second... no matter how many machines
> > you throw at it. Even on a single machine the central clock can cause
> > scalability problems (10/20M transactions/second and this will degrade
> > when you throw more cores at it).
> >
> > This is one of the reasons I dropped the TL2 approach for Multiverse
> > and switched over to the SkySTM model (with some magic of my own) that
> > doesn't relied as much on a central mechanism.
> >
> > On Jul 11, 6:50 pm, scx  wrote:
> >
> >
> >
> > > hi --
> >
> > > i've seen paul standig's work with clojure +terracotta.  wondering if
> > > anyone has continued his work?
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from 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: ANN: Deview - Better test results

2010-07-14 Thread Paul Stadig
On Wed, Jul 14, 2010 at 2:11 AM, Heinz N. Gies  wrote:

>
> On Jul 14, 2010, at 6:40 , Phil Hagelberg wrote:
>
> > This is really cool!
> >
> > Unfortunately since I spend all my time in the terminal, (for remote
> > pairing) I can't really use a web-based interface like this for normal
> > work. Do you have any plans to create a command-line client? How hard
> > would it be?
> >
> > Alternatively, do you know how much work it would be to wire difform
> > directly into clojure.test so you'd get readable results from a
> > standard "lein test" run?
> >
> Hi Phil,
> you could use SSH port forwarding, it works like a charm on both *nix and
> windows (with putty) so you can access a remote http server that runs 'in
> private'
>
> regards,
> Heinz
>

Port forwarding would still require switiching back and forth between a
terminal to a browser, no? It would be cool to have difform used in
clojure.test, so that test runs in a terminal could be grasped more
immediately.


Paul

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

2010-07-13 Thread Paul Stadig
I have not pursued any further work with Terracotta, because I haven't had a
real project that required it. I'd be glad to try to pick something back up,
especially if there are others interested in helping out.

Paul

http://paul.stadig.name/ (blog)
703-634-9339 (mobile)
pjstadig (twitter)
p...@stadig.name (jabber)

Projects
http://www.mycrossoverpoint.com/
http://www.reformedchurches.info/


On Mon, Jul 12, 2010 at 4:36 AM, peter veentjer wrote:

> I don't think it every is going to scale.
>
> MVCC/TL2 based STM designs rely on a central clock, so if you can
> update the clock in 0.1 ms on all machines, the maximum throughput is
> 1/0.0001 = 10.000 transactions/second... no matter how many machines
> you throw at it. Even on a single machine the central clock can cause
> scalability problems (10/20M transactions/second and this will degrade
> when you throw more cores at it).
>
> This is one of the reasons I dropped the TL2 approach for Multiverse
> and switched over to the SkySTM model (with some magic of my own) that
> doesn't relied as much on a central mechanism.
>
> On Jul 11, 6:50 pm, scx  wrote:
> > hi --
> >
> > i've seen paul standig's work with clojure + terracotta.  wondering if
> > anyone has continued his work?
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from 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

1.0 Compatible Terracotta Integration Module

2009-12-10 Thread Paul Stadig
Hey everyone,
I haven't been in #clojure that often lately, but when I have been
there were people asking about Terracotta integration on two separate
occasions. What are the chances of that?! :)

There is a new repo at http://github.com/pjstadig/tim-clojure-1.0.0/
that has a 1.0 compatible version of the TIM. It should be simpler to
setup and test (though it still depends on Maven...sorry). This time
around I also tested it on Windows, because I know a couple people
have asked about that.

Not everything in Clojure is functional, so there is a loss of
functionality from my last experiment, but this release also changes
the way that the sharing occurs. Vars are shared in Terracotta based
on metadata. So, for example, if you wanted to define a new shared
Var, then you would do it like so:

(defn #^{:tcshared true} foo [] 42)

To remove an object from Terracotta you would alter is metadata like
so:

(alter-meta! #'foo assoc :tcshared false)

By default everything that can be shared from clojure.core and
clojure.main are shared (obviously I'll need to share the other
clojure.* namespaces). This is still early, so some things will
change, but I wanted to get it out there as early as possible, while
still being functional. You can track the progress by watching either
the Git repo, or my blog http://paul.stadig.name/, and I would
certainly welcome any feedback or contributions.


Paul

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

2009-11-18 Thread Paul Stadig
Thanks for your feedback.

I was able to get it to work again and pushed some minor changes to
the git repo. I downloaded Terracotta 3.1.1, and followed the
instructions in the tim-clojure-1.0-SNAPSHOT/example/README. I ended
up uncommenting all of the code in ClojureTerracottaConfigurator.java.
I believe I had commented it out, because some of the replacement
classes were not necessary anymore, and I was going to trim it down to
the essential replacements, but I never finished the work.

The error you are experiencing might be because of one of the
outstanding issues. A non-portable class cannot be used as a root
binding for any Var. As I mentioned before, I have an idea for a
workaround, but have not pursued it as yet. If you'd like to help,
then let me know.


Paul

On Nov 17, 12:43 pm, Sergey Didenko  wrote:
> Hi Paul,
>
> the code from [1] does not work under the latest Terracotta (3.1.1)
> with clojure-slim.jar's in the following combinations:
>
> 1) branch "1.0.x" from [3]
> 2) branch "1.0.x" from [3] + modified
> ClojureTerracottaConfigurator.java (uncommented lines)
> 3) [2] svn revision 1335 + modified ClojureTerracottaConfigurator.java
> (uncommented lines)
> 4) [2] svn revision 1310 + modified ClojureTerracottaConfigurator.java
> (uncommented lines)
>
> Terracotta writes messages like
>
> "Non-portable field name   : clojure.lang.Var.root
> Unshareable class         : clojure.lang.XMLHandler
> "
>
> [1]http://github.com/pjstadig/tim-clojure-1.0-snapshot
> [2]http://clojure.googlecode.com/svn
> [3]http://github.com/richhickey/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


Re: Clojure & Terracotta - TIM

2009-11-16 Thread Paul Stadig
Sorry! I forgot to say this, but the short answer is: No, I would not
consider it to be production ready. It may be close, but it is not
production ready.


Paul

On Sun, Nov 15, 2009 at 2:47 PM, Sergey Didenko wrote:

> Hi from a Clojure newbie!
>
> I have read the april thread "Clojure + Terracotta Update" and it
> looks pretty positive.
>
> A few question for TIM users:
>
> Is there newer version than
> http://github.com/pjstadig/tim-clojure-1.0-snapshot ?
>
> Are there still bugs?
>
> Can it be called production ready?
>
> Regards, Sergey.
>

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

2009-11-16 Thread Paul Stadig
Hey Sergey,
I did the work on the Clojure TIM. I published a report of my findings at
[1]. At least three of the roadblocks that I encountered were fixed in
Terracotta 3.0.1 [2].

I believe the TIM works with Clojure 1.0, but it's been several months since
I've looked at the code. There are still some issues with the Terracotta
Integration:

1. It requires runtime replacement of some Clojure classes (which is fairly
simple with Terracotta). It would be nice if these changes could be
integrated into the Clojure codebase. It is daunting to think of having to
maintain a set of changes that are replaced at runtime by Terracotta, but
this could be done against each stable release of Clojure.

2. Currently the Clojure TIM shares all Vars, which causes a problem because
the root binding of a Var can possibly be a non-portable class (such as an
IO stream, or database connection...instances of these cannot meaningfully
be shared across VMs). One (currently half pursued avenue) is to setup a way
to share only certain Vars perhaps by adding some metadata that indicates
the Var should be shared.

3. There is still a problem about how dynamically compiled classes should be
shared across VMs. I believe the current TIM just permanently caches
dynamically compiled classes, and they are never garbage collected. This
might be a problem if many dynamically compiled classes are created, but in
practice it may not be a problem depending on the circumstances.

I would love to hear of people's experience using this TIM. This was an
academic exercise for me and I have not pursued this much more, because I'm
not using it, and I haven't heard from anyone who is using it. I'd be glad
to pick back up on this work and/or to add accept contributions from others.

Paul


[1] http://docs.google.com/Doc?id=dg7c7v49_241g5t8tqsv
[2] http://paul.stadig.name/2009/04/terracotta-bug-reports.html

On Sun, Nov 15, 2009 at 2:47 PM, Sergey Didenko wrote:

> Hi from a Clojure newbie!
>
> I have read the april thread "Clojure + Terracotta Update" and it
> looks pretty positive.
>
> A few question for TIM users:
>
> Is there newer version than
> http://github.com/pjstadig/tim-clojure-1.0-snapshot ?
>
> Are there still bugs?
>
> Can it be called production ready?
>
> Regards, Sergey.
>

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

2009-06-17 Thread Paul Stadig
On Wed, Jun 17, 2009 at 7:03 AM, Mark Volkmann wrote:

> On Tue, Jun 16, 2009 at 8:17 PM, Antony Blakey wrote:
>
> We must be talking about a different way of using git. In my case I created
> a local repo from the remote github repo using the following command:
>
> git clone git://github.com/richhickey/clojure.git
>
> After doing this, I still contend that the correct way to update my local
> repo is to cd to the directory of my local repo and run "git pull". Do you
> think that's wrong? It seems to me in this scenario the command we shouldn't
> use it "git push" because that would attempt push my changes back to the
> github repo.


Mark,
You are correct. The way that you should update *your* repository is to
issue the "git pull" command within the working directory. Look at it from
Rich's perspective. There are two ways that he can get changes from your
repo into his repo. One is for you to cd into your directory and issue a
"git push" command, but that assumes that you have access to write to his
repo.

The other way is for him to cd into his directory and issue the "git pull"
command. This only assumes that he has read access to your repo. There is a
feature of GitHub (the website, not git itself) that is called a "pull
request". You do not have write access to Rich's repo, but you want him to
incorporate your changes, so you send him a "pull request". It is basically
just an e-mail saying, "Hey, Rich, I have a cool new change that I'd like to
see incorporated, cd into your working directory and issue a 'git pull'."

Rich has said to hold off on sending "pull requests" through the GitHub
website. He is not saying that you cannot update your repo.


Paul

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

2009-06-16 Thread Paul Stadig
On Tue, Jun 16, 2009 at 1:38 PM, Michel Salim wrote:

>
> It's currently not possible to dynamically rebind functions:
>
> (binding [+ -] (+ 5 3)) ==> 8 ;; not 2
>
> Thanks,
>
> --
> Michel S.
>

It is possible to rebind (even core) functions, but there are a couple of
limitations. One of which is the fact that some functions are inlined by the
compiler. I believe the two argument case of '+ is one of those.

Paul

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

2009-06-16 Thread Paul Stadig
On Wed, Jun 10, 2009 at 11:37 AM, Stuart Sierra  wrote:

>
> On Jun 9, 10:32 am, Stuart Sierra  wrote:
> > Join us Tuesday, June 9 from 7:00-9:00 for Stuart Sierra's
> > presentation:
> >
> > Implementing AltLaw.org in Clojure
>
> Slides and video here: http://lispnyc.org/wiki.clp?page=past-meetings
> We'll try to get something lighter than a 3GB mpeg soon.
>
> -Stuart
>

I watched this video. Thanks for posting it! There is some great information
in there, especially the "from the trenches" tips about working with Java
libraries.

Since you're one of the more active contributors to Clojure, would it be
appropriate to post the video to clojure.blip.tv?


Paul

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

2009-06-11 Thread Paul Stadig
I believe David Miller is the one who wrote the CLR code, and he is still
hacking on it when he has time.

In addition to what is checked into contrib there is also this:

http://github.com/dmiller/ClojureCLR/tree/master

I'm not sure if they are in sync or which is the most current (github may be
it was last updated May 31). I suppose one possible workflow is to fork,
improve, and set a pull request.


Paul

On Wed, Jun 10, 2009 at 10:25 PM, mmwaikar  wrote:

>
> Hi,
>
> How can one contribute to the development of Clojure on CLR?
>
> I was trying the following - (.ToString DateTime/Now) and was getting
> - "System.Exception: Unable to find static field: Now in
> System.DateTime".
>
> I added some code in Reflector.cs, Compiler.cs and StaticFieldExpr.cs
> and got it working, though I am not sure if the fixes are in the right
> place. Please let me know if you want to have a look at my changes.
>
> Thanks,
> Manoj.
>
> >
>

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

2009-06-05 Thread Paul Stadig
Concepts of Programming Languages by Sebesta is a book that we used that as
the text for my comparative programming languages class. I haven't read
CTMCP, so I cannot compare. However, after taking that class during my
undergraduate, I couldn't believe that it was an elective! There should
definitely be a "models of programming languages" class as a core
requirement for any computer science curriculum. My CS program required a
formal models class, but learning about machine models is very different
from learning about the history, evolution, and paradigms of programming
languages.

I have read SICP, and it is very much worth reading. I'm not sure it was as
general as Sebesta's book, but certainly a classic that any (Lisp) hacker
should read.


Paul

On Fri, Jun 5, 2009 at 11:40 AM, Laurent PETIT wrote:

>
> Yes,
>
> It's rare to see books about programming concepts/models and not
> programming languages.
>
> As far as I know the following 3 ones deserve being mentioned :
>
>  * OOSC: Object Oriented Software Construction ( general about object
> orientation, see http://archive.eiffel.com/doc/oosc/page.html )
>  * SICP: Structure and Interpretation of Computer Programs ( general,
> see http://mitpress.mit.edu/sicp/full-text/book/book.html )
>  * and now CTMCP: Concepts, Techniques and Models of computer
> programming ( covering all programming concepts/models, aka
> functional, imperative, object oriented, data flow, ... : see
> http://www.info.ucl.ac.be/~pvr/book.htm)
>
> I haven't yet finished CTMCP, but I hope it will help me move from the
> "I know one programming model (e.g. either object oriented, either
> functional, ...) / I switch from one programming model to another, and
> I systematically consider the new one as a best fit for any job"
> attitude
> to
> "I now have knowledge to choose the right tool (programming model) for
> the job at hand (software to build)".
>
> Hopefully, clojure seems multi-paradigms enough to be able to stay
> within the same language while switching from one paradigm to another
> depending on the subsystems or parts of subsystems to implement !
>
> That also, is for me a big strenght of clojure compared to e.g. java.
>
> Regards,
>
> --
> Laurent
>
> 2009/6/5 Daniel Jomphe :
> >
> > I support the CTMCP recommendation. I learned a lot from its first few
> > hundred pages. (Kept the rest for later.)
> >
> > On Jun 5, 2:45 am, Laurent PETIT  wrote:
> >> I just got my own copy of the CTM book (Concepts, Techniques and
> >> Models of computer programming) (
> http://www.info.ucl.ac.be/~pvr/book.html)
> and from now on I find it
> >> very interesting in introducing all these notions (variable, value,
> >> binding, etc.) one step after the other, showing how the different
> >> programming models / programming paradigms relate to each other,
> >> complement themselves, etc.
> >>
> >> I encourage you to get your own copy.
> > >
> >
>
> >
>

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

2009-06-02 Thread Paul Stadig
On Tue, Jun 2, 2009 at 10:06 AM, Shawn Hoover wrote:

> On Tue, Jun 2, 2009 at 9:52 AM, Michael Reid  wrote:
>
>> On Fri, May 29, 2009 at 2:51 PM, Paul Stadig  wrote:
>> > You meant to type disclosure, but instead you typed disclojure.
>> >
>> > Paul
>> >
>> How about when you try to write code in other languages, and
>> reflexively place parentheses before function/method names?
>>
>> (len 'Foo') <-- not valid Python. :(
>>
>> /mike.
>
>
> Don't forget, commas are NOT optional!
>
> irb(main)> a = [1 2 3]
> SyntaxError: compile error!
>

Hehe, yeah that one's gotten me before. :)

Paul

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

2009-06-02 Thread Paul Stadig
I signed up and voted. Only took about 30 seconds.

Thanks for the work everyone. I would love to see Clojure get into the Maven
repo.


Paul

On Tue, Jun 2, 2009 at 6:04 AM, Stefan Hübner wrote:

>
> The upload bundle, which is found at
> http://jira.codehaus.org/browse/MAVENUPLOAD-2464, promotes Clojure as
> "org.clojure:clojure:1.0.0". It hasn't received any atention from the
> Upload team yet, but I do hope it gets uploaded within the next
> weeks. Maybe voting could speed it up...
>
> dysinger  writes:
>
> > I personally have used the -lang qualifier in my own POM work so as to
> > have an (unspoken) consensus with Howard's POM work.
> >
> > However, I would rather clojure proper just be named
> > "org.clojure:clojure" in maven/ivy-land myself and I have heard that
> > from quite a few others.
> >
> > On May 10, 1:17 pm, d...@kronkltd.net (Daniel E. Renfer) wrote:
> >> Phil Hagelberg  writes:
> >> > Howard Lewis Ship  writes:
> >>
> >> >> clojure-lang because there will be a clojure-contrib artifact for the
> >> >> same group.
> >>
> >> > And this is ... a bad thing? I'm lost.
> >>
> >> > -Phil
> >>
> >> Good, at least I'm not the only one.
> >>
> >> Why can't we have both clojure and clojure-contrib as Id's?
> >>
> >> Daniel E. Renfer
>
>
> >
>

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

2009-05-29 Thread Paul Stadig
You meant to type disclosure, but instead you typed disclojure.

Paul

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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-mode install on Windows XP does not work, for me

2009-05-19 Thread Paul Stadig
I don't think I did anything special. All I did was install clojure,
clojure-contrib, slime, and swank-clojure using the M-x clojure-install
command from clojure-mode. I'm pretty sure it doesn't make a difference, but
I'm also running on a snapshot of Emacs.

Aside from that I just added the below to my .emacs file and I was up and
running.

The error that occurs when starting up the REPL is that it cannot find
swank.swank, which means that swank clojure is not on the classpath. Adding
it to the swank-clojure-extra-classpaths will cause it to pass that in the
-cp parameter for java, which should allow the REPL startup script to find
swank.swank.

The REPL startup is using 'add-classpath to try to add the swank.swank
namespace to the classpath, but it is obviously not working, which is why I
thought it might be a problem with add-classpath.


Paul

On Mon, May 18, 2009 at 2:40 PM, klang  wrote:

>
> Using my existing definitions
>
> (setq clojure-src-root "~/lisp/clj")
>
> (setq swank-clojure-extra-classpaths
>  (cons (concat clojure-src-root "/swank-clojure")
>(when (file-directory-p "~/.clojure")
>  (directory-files "~/.clojure" t ".jar$"
>
> This does not work, with "origin/master", rolling back to "origin/1.0"
> works though. (with or without setting swank-clojure-extra-classpaths)
>
> Paul, you must have done something else to swank-clojure to make thing
> work on origin/master?
>
> /klang
>
> On May 18, 7:14 pm, Paul Stadig  wrote:
> > I just happened to be setting up emacs an a new Ubuntu install today. I
> > think it might have something to do with 'add-classpath. The
> > swank-clojure-init function is trying to add the swank-clojure directory
> to
> > the classpath, but the 'require still fails when starting up the clojure
> > REPL.
> >
> > I added the following to my .emacs to get it to work:
> >
> > (setq swank-clojure-extra-classpaths
> >   (cons "~/src/swank-clojure"
> > (when (file-directory-p "~/.clojure")
> >   (directory-files "~/.clojure" t ".jar$"
> >
> > Paul
> >
> > On Mon, May 18, 2009 at 1:02 PM, Phil Hagelberg  wrote:
> >
> > > klang  writes:
> >
> > > > First things first:
> >
> > > > swank doesn't load and slime can't connect to the *inferior-lisp*
> > > > running clojure
> >
> > > > I am missing something obvious, please advice.
> >
> > > It's not your fault; it looks like the latest Clojure 1.1 snapshot is
> > > not compatible with swank-clojure. I haven't been following it closely,
> > > but somewhere between 1.0 and the present it's broken. It looks like
> > > swank-clojure will need to be updated to work with the latest.
> >
> > > In the meantime, cd to your checkout of clojure and perform:
> >
> > >  $ git checkout origin/1.0
> > >  $ ant
> >
> > > Then launch a new Emacs instance and M-x slime should work. This did
> the
> > > trick for me at least. I'll update clojure-mode to work with 1.0 by
> > > default so you don't need to do anything by hand.
> >
> > > -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
To unsubscribe from 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-mode install on Windows XP does not work, for me

2009-05-18 Thread Paul Stadig
I just happened to be setting up emacs an a new Ubuntu install today. I
think it might have something to do with 'add-classpath. The
swank-clojure-init function is trying to add the swank-clojure directory to
the classpath, but the 'require still fails when starting up the clojure
REPL.

I added the following to my .emacs to get it to work:

(setq swank-clojure-extra-classpaths
  (cons "~/src/swank-clojure"
(when (file-directory-p "~/.clojure")
  (directory-files "~/.clojure" t ".jar$"


Paul

On Mon, May 18, 2009 at 1:02 PM, Phil Hagelberg  wrote:

>
> klang  writes:
>
> > First things first:
> >
> > swank doesn't load and slime can't connect to the *inferior-lisp*
> > running clojure
> >
> > I am missing something obvious, please advice.
>
> It's not your fault; it looks like the latest Clojure 1.1 snapshot is
> not compatible with swank-clojure. I haven't been following it closely,
> but somewhere between 1.0 and the present it's broken. It looks like
> swank-clojure will need to be updated to work with the latest.
>
> In the meantime, cd to your checkout of clojure and perform:
>
>  $ git checkout origin/1.0
>  $ ant
>
> Then launch a new Emacs instance and M-x slime should work. This did the
> trick for me at least. I'll update clojure-mode to work with 1.0 by
> default so you don't need to do anything by hand.
>
> -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
To unsubscribe from 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: Google App Engine - best workflow

2009-05-15 Thread Paul Stadig
I'm not a java security manager expert, but I've been playing with this a
bit.

Could you not do it the other way round? Start a REPL and run the server in
the REPL, instead of starting a server and trying to run a REPL in the
server?

I got as far as setting up the classpath and doing:

(com.google.appengine.tools.development.DevAppServerMain/main (into-array
["war"]))

But of course I get an exception when it tries to install its security
manager. Is it possible to create a java policy file that would allow it to
succeed?


Paul

On Wed, May 13, 2009 at 11:21 PM, Victor Rodriguez wrote:

>
> On Wed, May 13, 2009 at 5:35 PM, Kees-Jochem Wehrmeijer
>  wrote:
> >
> > Hi everybody,
> >
> > I started playing with Clojure on Google App Engine. By following the
> > experiences of others (http://elhumidor.blogspot.com/2009/04/clojure-
> > on-google-appengine.html and
> http://www.fatvat.co.uk/2009/05/clojure-on-google-app-engine.html
> > mostly) I was able to get something running quite quickly. However,
> > something that annoys me is that I have to recompile every time I make
> > a change. I'm still learning Clojure (and Emacs) but I'd already
> > gotten quite used to using the REPL. So I was wondering if anybody
> > else already had some experience with using Clojure on GAE and what
> > your workflow looks like.
>
> If you feel like it, you can try to decompile the class that installs
> the security manager in Google's SDK and change it so that you start a
> REPL from the development server.
>
> I have got as far as starting the REPL, but I have yet to find the
> time to use this setup, so there might be other "showstoppers".
>
> Cheers,
>
> Victor Rodriguez.
>
>
> > cheers,
> > Kees
> > >
> >
>
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: Macros applied to entire programs

2009-05-12 Thread Paul Stadig
You could write a Clojure program that took in a Clojure program and spit
out an optimized Clojure program. You could do something similar to the
meta-circular evaluator, where you step through the program (which is just a
data structure) recursively matching the head each time against different
symbols. In your case you could match against '+ and do something special,
but as Konrad mentioned there are some difficulties with that.

Another possibility would be to write a macro called my-+ or ++ or
something, and use that instead. This would be a simple solution, because
you wouldn't have to rewrite all of the matching for all of the different
forms. The only problem would be that you'd have to change any existing
code, but at least that way you'd be optimizing the parts of your code that
need it and it would be clear what you are doing. You could also exclude
clojure.core/+ from your namespace and write a macro called + that would
then call clojure.core/+. I'm not sure if the following code works and is
bug-free, but it'd be something like:

(ns test
  (:refer-clojure :exclude [+]))

(defmacro +
  ([] 0)
  ([a] `(clojure.core/+ ~a))
  ([a b] `(clojure.core/+ ~a ~b))
  ([a b & c] `(clojure.core/+ ~a (+ ~b ~...@c

There are some "challenges" to having '+ or my-+ or ++ be a macro, it means
that you would have to wrap it with a function literal before you could pass
it to functions like 'map.

It is true that '+ gets inlined with two arguments, so it is faster than
calling it with three or more arguments. Another possibility would be to
just discipline yourself to use the two argument form instead of the three
or more argument form.


Paul

On Mon, May 11, 2009 at 11:42 PM, Mark Reid  wrote:

>
> Hi,
>
> I'm quite new to macros so forgive me if this is a naïve question, but
> is it possible to write macros that are applied to an entire Clojure
> program?
>
> The reason I ask is that, in other threads in this group, some simple
> transformations to improve efficiency of Clojure programs were
> mentioned. In particular, it seems converting `(+ 1 2 3)` to `(+ 1 (+
> 2 3))` can speed things up. Applying such a transformation to my own
> code would be a mindless pattern matching job, and thus perfect for
> automation.
>
> Any suggestions how I might write a Clojure program that takes as
> input another Clojure program and outputs a third one that is
> optimised but semantically equivalent to the input? Are macros the
> right tool for the job in this case?
>
> Thanks,
>
> Mark.
> --
> http://mark.reid.name
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: Got a Clojure user group?

2009-05-05 Thread Paul Stadig
I manage the Clojure Users Group on LinkedIn, which might also be worth
mentioning.

http://www.linkedin.com/groups?gid=1058217


Paul

On Thu, Apr 23, 2009 at 9:43 PM, Rich Hickey  wrote:

>
> Thanks all - the list is here:
>
> http://clojure.org/community
>
> More additions welcome!
>
> Rich
>
>
> On Apr 15, 1:48 pm, Amit Rathore  wrote:
> > Hi Rich,
> >
> > Bay Area Clojure User Grouphttp://
> www.meetup.com/The-Bay-Area-Clojure-User-Group/
> >
> > Thanks!
> >
> > Regards,
> > Amit Rathore.
> >
> > On Apr 9, 12:00 pm, Rich Hickey  wrote:
> >
> > > Got a Clojure user group, meetup etc?
> >
> > > Reply to this message and let me know, I'll add them to the Clojure
> > > site.
> >
> > > Please supply a primary URL for getting info for your group.
> >
> > > Thanks!
> >
> > > Rich
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: ICFP 2009

2009-04-23 Thread Paul Stadig
On Thu, Apr 23, 2009 at 11:04 AM, Rich Hickey  wrote:

> On Apr 23, 8:59 am, Andrew Wagner  wrote:
> > > Sounds like a fun thing to try.  Could someone give a brief
> > > description of what would be required in terms of time commitment to
> > > participate on a team?  (Sadly, spare time is hard to come by...)
> >
> > It's just one weekend. As much or as little time as you can commit to for
> > that weekend.
>
> Although being competitive requires pretty much all waking hours
> during that weekend :)
>
> Rich
>

And some non-waking hours! :)

Paul

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: The Path to 1.0

2009-04-21 Thread Paul Stadig
On Mon, Apr 20, 2009 at 8:52 PM, Rich Hickey  wrote:

> On Apr 20, 2009, at 7:02 PM, Antony Blakey wrote:
> > On 21/04/2009, at 5:12 AM, Laurent PETIT wrote:
> >
> >> { :major 1 :minor 0 :release 0 :status :SNAPSHOT }
> >> then
> >> { :major 1 :minor 0 :release 0 :status :RC1 }  (release candidate 1)
> >> then
> >> { :major 1 :minor 0 :release 0 :status :RC2 }  (release candidate 2)
> >> etc.
> >> and finally
> >> { :major 1 :minor 0 :release 0 :status :GA1 } (Global Availibility 1)
>
> I'm unfamiliar with the POM version coordinate system - any hints?
>
> Rich
>

Others have commented on the whole groupId, artifactId, etc., etc. But in
terms of the parts of the version number, they are named
..- as documented here:

http://www.sonatype.com/books/maven-book/reference/pom-relationships-sect-pom-syntax.html


Paul

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: The Path to 1.0

2009-04-17 Thread Paul Stadig
On Fri, Apr 17, 2009 at 9:21 AM, Rich Hickey  wrote:

> 
>
> As for tests, there are tests in:
>
>
> http://code.google.com/p/clojure-contrib/source/browse/#svn/trunk/src/clojure/contrib/test_clojure
>
> Anyone who wants more tests can contribute them.
>

I think what would be useful, though, is to have a test suite with the
Clojure code. That way the suite is branched with the Clojure code. If a 1.0
branch is created in the Clojure code, then how does the test-clojure suite
relate to that? Would there be a 1.0 branch made of clojure-contrib, too?
Would there be any assurance that version X of the test-clojure suite can be
run against version X.Y of Clojure to verify there were no regressions?

And on clojure-contrib in general, I think maybe there needs to be a better
definition of what its scope is. Just because I have cool-whizz-bang Clojure
library does it mean that cool-whizz-bang should be made part of
clojure-contrib? clojure-contrib is for "user contributed code", but just
any code at all? As others have mentioned, clojure-contrib seems to include
some things that might warrant separate projects (like ClojureScript and
ClojureCLR). I don't see a problem with people creating Clojure libraries
and distributing them apart from clojure-contrib, but of course as soon as
the code starts to get distributed in different channels, you have the
dependency management issue. (ugh!)

Overall, I'm getting feature requests (more change!) and not a strong
> drive for 1.0 stability. If you feel otherwise, please speak up.
> Otherwise, my conclusion is that 1.0 may be more important for not-yet-
> users wary of working from source.
>

I don't think that feature requests preclude a 1.0 release. I think all that
is warranted is partitioning the feature requests into releases. 1.0 will
include x, y, and z (and are labeled with Release-1.0 in the issue tracker).
2.0 will include a, b, and c (and are labeled so). As soon as x, y, and z
are completed, then you cut a 1.0 release. (*brushes off hands* "Now we
start on 2.0.") Of course you would have the flexibility (within reason) of
shifting features to earlier or later releases.

If a bug fix comes in, and it is determined that it should be backported
from trunk to the 1.0 branch, then label it so in the issues tracker, and
the 1.0 release captain can modify the test suite, and cut a 1.0.1 release.
There is already a list of "Primary Contributors" on the clojure.org site. I
nominate them as release captains :). I don't think that Rich needs to be
bothered with that sort of thing. I hesitate to say this, but if no one else
will do it, then I'll volunteer, since I got a pretty good idea of the inner
workings of Clojure with my Terracotta work.

All that said, Rich, don't feel rushed into making decisions about this. If
you're not comfortable, cutting a 1.0 release and starting the whole release
management process, then don't. It's getting close, but maybe it's not time
just yet. However, I don't think it's a matter of having to stop progress,
but just to create check points along the way, and to give people that
psychological ease of seeing 1.0.


Paul

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: java.lang.String cannot be cast to [Ljava.lang.CharSequence;

2009-04-16 Thread Paul Stadig
Are you trying to give it a string, or an array of strings?

sendKeys takes a variable number of arguments. The error you are getting is
that it can't cast a java.lang.String into [Ljava.lang.CharSequence, where
the '[' at the beginning of the type means an array. It is telling you that
it cannot convert a String into an array of CharSequences. Maybe it will
work with (into-array ["string"])?


Paul

On Thu, Apr 16, 2009 at 2:25 PM, prhlava  wrote:

>
>
> Hello,
>
> I am trying to use a java library ( http://code.google.com/p/webdriver/
> ), the method I need to call has signature:
>
> sendKeys(java.lang.CharSequence... keysToSend)
>
> If I give it a clojure string, the "cannot be cast" message appears in
> the stack trace.
>
> I have tried explicit (cast java.lang.CharSequence "my-string") but
> the cast does only "compare" AFAIK.
>
> Is there a way to give the library what it wants from Clojure?
>
> Kind regards,
>
> Vlad
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: DISCUSS: clojure.contrib.java-utils/as-str

2009-04-09 Thread Paul Stadig
I think it makes sense for (str) to return "", but I'm not sure about
(as-str) being "". It doesn't seem as obvious and expected to me.


Paul

On Thu, Apr 9, 2009 at 2:57 AM, Eric Tschetter  wrote:

>
> Might I suggest
>
> (defn as-str
>  ([] "")
>  ([& args]
>(apply str (map #(if (instance? clojure.lang.Named %) (name %) %)
> args)))
>
> --Eric Tschetter
>
> On Wed, Apr 8, 2009 at 8:19 PM, Stephen C. Gilardi 
> wrote:
> >
> > On Apr 8, 2009, at 8:13 PM, Stuart Halloway wrote:
> >
> >> Changed to as-str (r654).
> >
> > Very nice!
> >
> > Should we extend as-str to any number of arguments like its close cousin
> > str?
> >
> > Here's a proposed implementation:
> >
> > (defn as-str
> >  "With no args, returns the empty string. With one arg, returns its name
> >  or string representation. (as-str nil) returns the empty string. With
> >  more than one arg, returns the concatenation of the as-str values of the
> >  args."
> >  {:tag String}
> >  ([] "")
> >  ([x]
> > (if (instance? clojure.lang.Named x)
> >   (name x)
> >   (str x)))
> >  ([x & ys]
> > (let [sb (StringBuilder. #^String (as-str x))]
> >   (doseq [y ys]
> > (.append sb (as-str y)))
> >   (.toString sb
> >
> > Comments welcome.
> >
> > --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
To unsubscribe from 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 on Google AppEngine

2009-04-08 Thread Paul Stadig
Nice writeup John! Thanks very much.

Not sure if I made it into the first 10k developers, but I can't wait to
play with this.


Paul

On Wed, Apr 8, 2009 at 12:52 AM, David Nolen  wrote:

> Very exciting, thanks for the excellent and informative writeup.
>
>
> On Wed, Apr 8, 2009 at 12:41 AM, John D. Hume wrote:
>
>>
>> As predicted, Google has now released Java support for AppEngine. I
>> was lucky enough to get an early look, which I dedicated entirely to
>> Clojure.
>>
>> Here's a writeup:
>> http://elhumidor.blogspot.com/2009/04/clojure-on-google-appengine.html
>>
>> Have fun!
>> -hume.
>> --
>> http://elhumidor.blogspot.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
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: ANN: Pretty printer is now part of contrib

2009-04-07 Thread Paul Stadig
Isn't it somewhat standard procedure in the Java world (or at least the
Maven world...sorry to bring that up again :)) to distribute with a
clojure-contrib.jar and clojure-contrib-sources.jar, one being only the
compiled classes and the other only being the source files?


Paul

On Tue, Apr 7, 2009 at 8:17 AM, BrianS  wrote:

>
> I use clojure-contrib quite a bit, and I find a lot of value out of
> having the clj files in the JAR. First, I find it easier to debug a
> project, second there are example CLJ files in the source code on how
> to use the libraries, and those are of great interest, and it is much
> easier to get to these source files from my IDE if they are in the
> JAR.  I understand the value a smaller footprint JAR file, so maybe
> there can be a property either set in the ant file or allowed as a
> parameter of the build file to allow someone to build the lightweight
> version of clojure-contrib if needed? Just the point of view of a
> user, not a contributor, of clojure-contrib.
>
> Brian
>
> On Apr 7, 1:37 am, Laurent PETIT  wrote:
> > Hi,
> >
> > 2009/4/6 Tom Faulhaber 
> >
> > > Another question is whether we should duplicate the classes and
> > > the .clj files in the jar or should we just compile all of them. Is
> > > there some value to having the source there?
> >
> > There certainly some value for both scenario : having classes seems an
> > absolute requirement for some libraries to work, but having .clj files is
> > really interesting for those that want either (show-source) ... in their
> > REPL to work (or in IDEs for jumping to a read-only syntax-colored
> version
> > of the source file).
> >
> > But there is also certainly value in having a build with just the classes
> ?
> > (Though since the whole thing is open source, it's not a problem related
> to
> > rights, but maybe for some platforms such as Android, some people might
> want
> > the lightest possible jar ?)
> >
> > Regards,
> >
> > --
> > Laurent
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: Simple dosync/alter question

2009-04-06 Thread Paul Stadig
Alter expects a function that take the current value of the ref it will
alter as the first arg. I think what you want to do is ref-set.

user=> (doc alter)
-
clojure.core/alter
([ref fun & args])
  Must be called in a transaction. Sets the in-transaction-value of
  ref to:

  (apply fun in-transaction-value-of-ref args)

  and returns the in-transaction-value of ref.
nil
user=> (doc ref-set)
-
clojure.core/ref-set
([ref val])
  Must be called in a transaction. Sets the value of ref.
  Returns val.
nil

user=> (defn square-ref [x] (dosync (ref-set foo (square x
#'user/square-ref
user=> (square-ref 2)
4
user=> @foo
4


Paul

On Mon, Apr 6, 2009 at 3:02 PM, bgray  wrote:

>
> I have a some what (I believe) easy question.  Could someone let me
> know what I'm doing wrong?  A simplified version of what I'm trying to
> do looks like this:
>
> user=> (def foo (ref 0))
> #'user/foo
> user=> (defn square [x] (* x x))
> #'user/square
> user=> (defn square-ref [x] (dosync (alter foo square x)))
> #'user/square-ref
> user=> (square-ref 2)
> java.lang.IllegalArgumentException: Wrong number of args passed to:
> user$square (NO_SOURCE_FILE:0)
> user=> (doc square)
> -
> user/square
> ([x])
>  nil
> nil
> user=>
>
> Thanks,
> Brandon
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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 do you handle different string encodings?

2009-04-03 Thread Paul Stadig
Works For Me (TM).

user=> (def s "québécois français")
#'user/s
user=> (print s)
québécois françaisnil

Are you running on Windows, Mac, or Linux? Using the Sun JVM? Which revision
of Clojure?

p...@pstadig-laptop:~$ lsb_release -a
No LSB modules are available.
Distributor ID:Ubuntu
Description:Ubuntu 8.10
Release:8.10
Codename:intrepid

p...@pstadig-laptop:~$ java -version
java version "1.6.0_10"
Java(TM) SE Runtime Environment (build 1.6.0_10-b33)
Java HotSpot(TM) Server VM (build 11.0-b15, mixed mode)

p...@pstadig-laptop:~/clojure$ svn info
Path: .
URL: http://clojure.googlecode.com/svn/trunk
Repository Root: http://clojure.googlecode.com/svn
Repository UUID: a41a16f3-9855-0410-b325-31a011a03e7c
Revision: 1336
Node Kind: directory
Schedule: normal
Last Changed Author: richhickey
Last Changed Rev: 1335
Last Changed Date: 2009-03-19 09:51:32 -0400 (Thu, 19 Mar 2009)


Paul

On Fri, Apr 3, 2009 at 10:57 AM, Daniel Jomphe wrote:

>
> Now that I know for sure how to bind *out* to something else over
> System/out, it's time to bring back my encoding issues into scope:
>
>  (import '(java.io PrintWriter PrintStream))
>
>  (defmacro with-out-encoded
>[encoding & body]
>`(binding [*out* (java.io.PrintWriter. (java.io.PrintStream.
> System/out true ~encoding) true)]
>  ~...@body
>  (flush)))
>
>  (def nc "ISO-8859-1")
>
>  ;;; with a normal string
>  (def s "québécois français")
>
>  (print s)
>  ; quÔøΩbÔøΩcois franÔøΩaisnil
>
>  (with-out-encoded nc (print s))
>  ; qu?b?cois fran?aisnil
>
>  ;;; with a correctly-encoded string
>  (def snc (String. (.getBytes s nc) nc))
>
>  (print snc)
>  ; qu?b?cois fran?aisnil
>
>  (with-out-encoded nc (print snc))
>  ; qu?b?cois fran?aisnil
>
> I'm certainly missing something fundamental somewhere.
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: Keeping a ref and a DB in sync

2009-04-03 Thread Paul Stadig
I'll just throw this out there. It may not be exactly what you're looking
for, but you could use a Terracotta cluster. Terracotta will persist the
cluster to disk. If you have an existing database that you are working with,
then this may not help, but if you are starting from scratch you may not
need a database if you use Terracotta.


Paul

On Fri, Apr 3, 2009 at 5:02 AM, Brian Carper  wrote:

>
> Is there a safe way to keep the data in a Clojure ref and the data in
> a table in an external (e.g. mysql) database in sync, given concurrent
> creates/updates/deletes from within Clojure?
>
> I can't do a DB update from within a dosync because of retries.  If I
> send-off an agent for the DB update from within a dosync, it won't
> happen until after the dosync is done, and then if the DB update
> throws an exception, it'll be too late to rollback the ref and they'll
> be out of sync.  If I do the DB update and ref update separately,
> there's the potential for race conditions if things happen in between.
>
> Is manual locking the only way?
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: Every function is a thread in Clojure?

2009-04-03 Thread Paul Stadig
The operations will happen synchronously. Clojure will not add threading to
your code without you asking it to, but when you want to add threading there
are lots of great tools built-in to make it Easy On You (TM).


Paul

On Fri, Apr 3, 2009 at 9:36 AM, BerlinBrown  wrote:

>
> Someone correct me if I go wrong here.  But, from my understanding,
> every defined function in Clojure is an implementation of a thread?
>
> What is the goal in implementing in this fashion?  For example, if I
> am writing in imperative style:
>
> (println "First line")
> (println "Second line")
> (println "Third line")
>
> ...
>
> The operations have to occur synchronously.  What does adding Java
> threading add to the mix?
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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 + Terracotta Update

2009-04-02 Thread Paul Stadig
I've been speaking with the Terracotta engineers, so here is an update on a
couple of the issues:

1) array.clone(). It turns out this is a bug in Terracotta. They have
acknowledged it, and will be working to resolve it. However, they mentioned
(as I have found else where on the interweb[1][2]) that arraycopy is
slightly faster than array.clone(), though nothing to write home about, so
it may be worth rolling that change back into Clojure, or at least it won't
hurt.

2) AtomicReference. They seem to think that adding support for AR in
Terracotta is low hanging fruit for someone who wants to write a patch, and
somehow they roped me into doing it. ;)

3) Boolean.TRUE != Boolean.TRUE across VMs. This also is a bug that they are
working to resolve.

So it looks like three of the biggest issues I had to work around in getting
Clojure to work with Terracotta, will be resolved on the Terracotta side.
This means that the Terracotta Integration Module that I wrote[3] will
pretty much boil down to a configuration file.

I think the only other *serious* issue is the problem with *in*, *out*, and
*err*. Either they need to be made into "special" vars, or derefed
specially, because their root values cannot be put into the TC cluster.

That's all folks!


Paul

[1]
http://groups.google.com/group/comp.lang.java.programmer/msg/f63fdf8da28004f0
[2] http://www.javapractices.com/topic/TopicAction.do?Id=3
[3] http://github.com/pjstadig/tim-clojure-1.0-snapshot/tree/master

On Mon, Mar 30, 2009 at 7:38 PM, Rich Hickey  wrote:

>
>
>
> On Mar 30, 5:12 pm, Paul Stadig  wrote:
> > I have gotten to the point in my Clojure + Terracotta experiment, where I
> > believe all of the features of Clojure are functional (Refs, Atoms,
> > transactions, etc.). I do not have a way to extensively test the Clojure
> > functionality, but I have run the clojure.contrib.test-clojure test
> suites
> > successfully, as well as some simple tests on my machine.
> >
> > There are still some open issues (though not necessarily deal killers),
> and
> > given the limited extent to which I have tested this, I would not
> consider
> > this production quality in the least. I would welcome help from the
> Clojure
> > community in testing this integration module. I'm sure there are
> unexplored
> > corners.
> >
> > Being that several of the changes are relatively trivial, they could be
> > easily integrated back into the Clojure core. I have detailed as best as
> > possible the changes I had to make to Clojure in this report: Clojure +
> > Terracotta Integration Report
> > (http://docs.google.com/Doc?id=dg7c7v49_241g5t8tqsv)<
> http://docs.google.com/Doc?id=dg7c7v49_241g5t8tqsv>It
> > is very possible that I have misunderstood things, so if there is a
> > better way to accomplish any of the solutions, then let me know.
> >
> > I would welcome any comments, feedback, etc.
> >
>
> Thanks for the detailed report! I'll look through it soon.
>
> Rich
>
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: speed question

2009-04-02 Thread Paul Stadig
Yeah that works the same as defining a function, just more explicit. I was
looking for a way to define a constant and just use it as "my-const" without
having to use the parens to call a function or a macro. I guess that would
be something like a symbol macro in CL?


Paul

On Thu, Apr 2, 2009 at 11:08 AM, MikeM wrote:

>
> There is definline which seems appropriate in place of the constant
> macros.
>
> (definline my-const [] 1)
> (my-const) ;= 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
To unsubscribe from 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: speed question

2009-04-02 Thread Paul Stadig
I think you are right, Brad.

However, I wonder though if there is a better way to define a constant.
Neither the macro nor function seems clean. I like David's
wrapping-the-whole-thing-in-a-let, but what if you wanted to access the
value of "width" in a different file? Would one have to resort to defining a
Java class (at compile time or runtime)?


Paul

On Thu, Apr 2, 2009 at 10:47 AM, Bradbev  wrote:

>
> It would seem that macros in this case should not be required.  A
> normal function that simply returns a constant should get inlined by
> the JIT.
>
> Cheers,
> Brad
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: Ironicly Maven2 is the lightest I could come up with

2009-04-02 Thread Paul Stadig
This works great for Java libraries, but only libraries that are in a maven
repo. How hard is it to get code into a repo? What about java libraries not
in a maven repo, or clojure code like clojure-json on GitHub?

1. You could set up your own repo. Ok. Cool, but not the easiest to setup
and maintain, plus you need a server.

2. You could install dependencies in your local repo. Cool, if the project
happens to be using maven and you can to "mvn install". Uncool, if you have
to manually "install" it into your local repo. Also uncool, because I see my
local repo more as a cache that can sometimes get crufty and can be cleared
out if I need the disk space. Maven *should* be able to re-download my
dependencies and put them in my local repo, but not so for these manual
workarounds.

3. ???

I'm not trying to be disparaging. If this works for someone, I think it is
pretty slick. I'm still of the mind that there could be something better.
Something that can pull from a maven repo as needed, but also pull from
other sources like github, sourceforge, google code, etc. I'm just spoiled
by rubygems. This is an existence proof that there can be a simple way to
download and setup dependencies (not without foibles).

Perhaps if there was a Clojure Maven Repo (CMR) where people could easily
get their code distributed, then I would feel satisfied.

What happened to the ClojureForge idea from tech.coop? Did anything come
about from that, Drew? Perhaps just hosting CMR with some way to signup for
an account to be able to "mvn deploy"?


Paul

On Thu, Apr 2, 2009 at 1:25 AM, dysinger  wrote:

>
> ...for easy dependency management and no-compile project setup.
> https://github.com/dysinger/clojure-pom/tree
>
> Using maven only for the dependency management and to create a custom
> repl script allows me to still use emacs/slime for dynamic development
> of clojure code.
>
> My motivation is 3 fold:
>
> 1) I have lots of small modules and want convention over configuration
> (no boiler plate ant scripts or other such cut and paste)
>
> 2) I want access to the kabazillion libraries in the maven repos -
> just go look at mvnrepository.com for example.
>
> 3) Although I spent 10 years on Java, I am a dynamic language fan.  I
> don't care or want to AOT compile at the moment. I just want to setup
> the libraries that my clojure code depends on and start writing /
> prototyping clojure code in Emacs SLIME.
>
> I would love to hear some feedback and/or what other people have been
> working on.
>
> -Tim
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: speed question

2009-04-02 Thread Paul Stadig
I got it down to about 3 seconds. I did what William said, but the biggest
improvement was from changing the way *width*, *height*, and *max-steps*
were defined. I noticed that in the Java version they are constants, but in
the Clojure version they are Vars which means that inside your tight inner
loops you are dereferencing the vars multiple times. Vars are for thread
local values, but these values are not expected to change. I'm not sure the
best way to make these vars into constants, but I changed them into macros:

(defmacro *width* [] (float 640))

Then replaced instances of *width* with (*width*). The macros will get
compiled down to floats instead of resulting in multiple Var.deref calls
(and probably Number.floatValue calls) per loop iteration.

Here is the code:

(ns main
 (:import (java.awt Color Container Graphics Canvas Dimension)
  (javax.swing JPanel JFrame)
  (java.awt.image BufferedImage BufferStrategy)))

(set! *warn-on-reflection* true)

(defmacro *width* [] (float 640))
(defmacro *height* [] (float 640))
(defmacro *max-steps* [] (float 32))

(defn on-thread [#^Runnable f] (doto (new Thread f) (.start)))

(defn check-bounds [x y]
   (loop [px (float x)
  py (float y)
  zx (float 0.0)
  zy (float 0.0)
  zx2 (float 0.0)
  zy2 (float 0.0)
  value (float 0)]
  (if (and (< value (*max-steps*)) (< (+ zx2 zy2) (float 4.0)))
   (let [new-zy (float (+ (* (float 2.0) zx zy) py))
 new-zx (float (+ (- zx2 zy2) px))
 new-zx2 (float (* new-zx new-zx))
 new-zy2 (float (* new-zy new-zy))]
 (recur px py new-zx new-zy new-zx2 new-zy2 (inc value)))
   (if (== value (*max-steps*)) 0 value

(defn draw-line [#^Graphics g y]
   (let [dy (- 1.25 (* 2.5 (/ y (*height*]
 (doseq [x (range 0 (*width*))]
   (let [dx (- (* 2.5 (/ x (*width*))) 2.0)]
   (let [value (check-bounds dx dy)]
   (if (> value  0)
   (doto g
   (. setColor (Color. (* value (/ 255
(*max-steps*)
   (. drawRect x y 0 0

(defn draw-lines
   ([buffer g] (draw-lines buffer g (*height*)))
   ([#^BufferStrategy buffer g y]
 (doseq [y (range 0 y)]
(draw-line g y)
;(on-thread (draw-line g y))
(. buffer show


(defn draw [#^Canvas canvas]
   (let [buffer (. canvas getBufferStrategy)
 g(. buffer getDrawGraphics)]
 (draw-lines buffer g)))

(defn main []

 (let [panel (JPanel.)
   canvas (Canvas.)
   frame (JFrame. "Mandelbrot")]

   (doto panel
 (.setPreferredSize (Dimension. (*width*) (*height*)))
 (.setLayout nil)
 (.add canvas))

   (doto frame
 (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
 (.setBounds 0,0,(*width*) (*height*))
 (.setResizable false)
 (.add panel)
 (.setVisible true))

   (doto canvas
 (.setBounds 0,0,(*width*) (*height*))
 (.setBackground (Color/BLACK))
 (.createBufferStrategy 2)
 (.requestFocus))

   (draw canvas)))

(time (main))

~$ clojure /tmp/mandelbrot.clj
"Elapsed time: 3577.128587 msecs"


Paul

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: Advanced Practical Recursion in Lisp 1.0

2009-04-01 Thread Paul Stadig
On Wed, Apr 1, 2009 at 6:00 AM, David Sletten  wrote:

> [snip]
>
> Here's 'length' again:
> (((fn [m]
> ((fn [future]
>(m (fn [arg]
> ((future future) arg
>  (fn [future]
>(m (fn [arg]
> ((future future) arg ))
>   (fn [rec]
> (fn [l]
>   (if (empty? l)
> 0
> (inc (rec (rest l )))
>  '(a b c d e))
> => 5
>
> And 'reverse':
> (((fn [m]
> ((fn [future]
>(m (fn [arg]
> ((future future) arg
>  (fn [future]
>(m (fn [arg]
> ((future future) arg ))
>   (fn [rec]
> (fn [l]
>   (cond (empty? l) '()
> (empty? (rest l)) (list (first l))
> :else (cons (first (rec (rest l)))
> (rec (cons (first l)
>(rec (rest (rec (rest l  )))
>  '(a b c d e))
> => (e d c b a)
>
> Breathtaking in its elegance!
>

Indeed! :)


>
> I'm going to move forward with the negotiations, but I need to know
> if you, the Clojure community, are on board here. Ultimately the
> decision is going to come down to whether or not you find the APRiL
> 1.0 technology useful. Try it out and let me know your opinions.
>

I think I'll wait for APRiL 2.0. I often find that when I jump right into
version 1.0 of a product, I'm made a fool!


>
> Aloha,
> David Sletten
>

Paul

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: Parameter ordering on map/reduce

2009-03-31 Thread Paul Stadig

Hi Nathan,
There is actually a simple answer to your question. map can take a
fuction of multiple parameters along with multiple collections. i.e.

(defn f [x y] (+ x y))

(map f [1 2] [3 4])
=> (4 6)

(Warning I did this computation in the Clojure instance in my head, so
some details may be slightly off.)

Paul

On 3/31/09, Nathan Sorenson  wrote:
>
> First of all, I would like to thank Rich and this community for
> producing such a pleasurable language, and for putting up with with
> all the unpleasant nit-picking of new users. That being said...
>
> I am curious as to why the function parameter is specified before the
> collection parameter in map/reduce. I have never used a lisp before,
> and may not be aware of idiomatic style, but it seems to be the
> convention elsewhere in Clojure (assoc, conj, .method calls, etc...)
> to have the "altered" data structure be the first parameter.
>
> Would this not allow mixing map into a threaded expression:
>
> (-> [1 2 3]
>  (map inc)
>  (assoc 0 4)
>  (reduce +)
>  (conj :anotherthing))
>
> Perhaps this style is rare in practice? Certainly it is easy enough to
> write a custom map/reduce which acts this way, so I suppose my
> question is mostly philosophical.
>
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Clojure + Terracotta Update

2009-03-30 Thread Paul Stadig
I have gotten to the point in my Clojure + Terracotta experiment, where I
believe all of the features of Clojure are functional (Refs, Atoms,
transactions, etc.). I do not have a way to extensively test the Clojure
functionality, but I have run the clojure.contrib.test-clojure test suites
successfully, as well as some simple tests on my machine.

There are still some open issues (though not necessarily deal killers), and
given the limited extent to which I have tested this, I would not consider
this production quality in the least. I would welcome help from the Clojure
community in testing this integration module. I'm sure there are unexplored
corners.

Being that several of the changes are relatively trivial, they could be
easily integrated back into the Clojure core. I have detailed as best as
possible the changes I had to make to Clojure in this report: Clojure +
Terracotta Integration Report
(http://docs.google.com/Doc?id=dg7c7v49_241g5t8tqsv)It
is very possible that I have misunderstood things, so if there is a
better way to accomplish any of the solutions, then let me know.

I would welcome any comments, feedback, etc.

Paul

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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   >