Re: Keyword namespaces

2010-09-19 Thread Kyle Schaffrick
On Sun, 19 Sep 2010 23:07:55 +0200
Meikel Brandmeyer  wrote:

> Hi,
> 
> Am 19.09.2010 um 22:59 schrieb ataggart:
> 
> > Also note that the namespace portion of a keyword does not get
> > resolved against the current aliases.  E.g.,
> > user=> (require '[clojure.java.io :as io])
> > nil
> > user=> (= :io/foo :clojure.java.io/foo)
> > false
> 
> It does with ::.
> 
> user=> (= ::io/foo :clojure.java.io/foo)
> true
> 
> Sincerely
> Meikel
> 

Ah! I did not know it also did that. I always thought of it as "stick
the current ns on this keyword", rather than "resolve the namespace of
this keyword using normal resolution rules". Interesting!

So then it seems correct to say that unless you explicitly trigger
namespace resolution with ::, the namespace of a keyword is unrelated
to the aliases in the environment. I think that's pretty much what I
wanted to know, thanks!

-Kyle

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

2010-09-19 Thread Kyle Schaffrick
On Sun, 19 Sep 2010 12:22:54 -0700 (PDT)
ataggart  wrote:

> Unlike symbols, keywords just evaluate to themselves. The keyword :foo
> will not collide with a var foo, likewise keyword :my-ns/foo will not
> collide with var my-ns/foo.  So, if I understand you correctly, :xsl/
> value-of would work just fine.

Right, I understand that the keyword and the symbol themselves are
distinct. I guess what I'm asking about is the meaning of their
namespaces to the evaluator, and probably is best illustrated like this:

  user=> (require '[some.library :as xsl])
  nil
  ;; now the namespace "xsl" has semantic meaning on symbols when
  ;; they're evaluated in this context:
  user=> #'xsl/value-of
  #'some.library/value-of

Is there any situation where, in that examaple, the namespace "xsl" on
a keyword such as :xsl/value-of might be conflated with the namespace
alias "xsl" that I created with require? Or, does Clojure consider
keyword namespaces to be completely meaningless and opaque, the same
as it does with their names?

I can't find any situation where the two blur together except for
the ::keyword syntax, but I suspect this is nothing more than a
superficial syntactic trick. Still, I want to make sure I'm not missing
something.

-Kyle

> 
> On Sep 19, 11:56 am, Kyle Schaffrick  wrote:
> > Would it be correct to say that the namespace portions of keywords
> > are semantically opaque?
> >
> > In other words, if I have a keyword :my-ns/foo and a symbol
> > 'my-ns/foo, obviously the namespace in the symbol has semantic
> > meaning to the language when it's evaluated (or syntax-quoted), but
> > the namespace of the keyword does not appear carry that meaning,
> > almost as if they are in two separate "meta-namespaces". Is that
> > pretty much guaranteed as far as the language is concerned?
> >
> > I'm asking because I've become the latest in the line of Clojurians
> > to go tilting at the "SXML-in-Clojure" windmill, and if I decide
> > use the namespace portion of a keyword (for example :xsl/value-of)
> > I want to be certain it's always distinct in meaning from any
> > Clojure namespaces or aliases of the same name.
> >
> > The code I teased apart into this library currently uses keywords
> > like :xsl:value-of to distinguish XML namespaces from Clojure
> > namespaces, just as a matter of "that was the first thing I thought
> > of", but it would certainly be saner to stop wasting effort
> > splitting them apart by hand with string munging and simply bestow
> > my own meaning on the keywords' namespaces if the language itself
> > doesn't give them any meaning.
> >
> > Thanks,
> > -Kyle
> 

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


Keyword namespaces

2010-09-19 Thread Kyle Schaffrick
Would it be correct to say that the namespace portions of keywords are
semantically opaque?

In other words, if I have a keyword :my-ns/foo and a symbol 'my-ns/foo,
obviously the namespace in the symbol has semantic meaning to the
language when it's evaluated (or syntax-quoted), but the namespace of
the keyword does not appear carry that meaning, almost as if they are
in two separate "meta-namespaces". Is that pretty much guaranteed as
far as the language is concerned?

I'm asking because I've become the latest in the line of Clojurians to
go tilting at the "SXML-in-Clojure" windmill, and if I decide use the
namespace portion of a keyword (for example :xsl/value-of) I want to be
certain it's always distinct in meaning from any Clojure namespaces or
aliases of the same name.

The code I teased apart into this library currently uses keywords
like :xsl:value-of to distinguish XML namespaces from Clojure
namespaces, just as a matter of "that was the first thing I thought of",
but it would certainly be saner to stop wasting effort splitting them
apart by hand with string munging and simply bestow my own meaning on
the keywords' namespaces if the language itself doesn't give them any
meaning.

Thanks,
-Kyle

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

2010-08-05 Thread Kyle Schaffrick
On Fri, 6 Aug 2010 00:04:08 +0200
Laurent PETIT  wrote:
> 
> No offense, but ... are you serious ?

So my off-the-cuff, wrote-it-in-5 minutes code is laughable? If you
mean no offense then why say this at all?

:(

> 
> I still prefer my own version, repeated here for the record :
> 
> (ns delay.util)
> 
> (defprotocol Cancellable (isCancelled [this]) (cancel [this]))
> 
> (defn timed-delay [pause fun]
>   (let [d (delay (fun))
> f (future (Thread/sleep pause) @d)]
> (reify
>   clojure.lang.IDeref
> (deref [_] @d)
>   delay.util.Cancellable
> (isCancelled [_] (future-cancelled? f))
> (cancel [_] (future-cancel f)
> 
>  -> the deref is on a delay, so it's causing no harm.
>  -> the code does not try to do "too much at once" : it only deals
> with one value, letting the client decide if the succession of values
> should be stored in an atom, in a ref, etc.
> 

I can agree it does do a better job of separating the time-delayed
concept from the rest of the problem than what I wrote.

I suppose I misunderstood what you were asking about, since this
doesn't appear to be the whole solution to the original scenario you
spoke of: your consumer must cancel the old and create a new
timed-delay manually if they wish to supersede the input value (i.e.
whenever the user types something).

But of course, if this is the contract you need then by all means, it's
certainly much better. (Although, Java's big scary list of caveats and
gotchas surrounding Future.cancel() kinda bother me personally...)

> Still not perfect for the names, but currently quite satisfied by the
> feature/code lines and feature/code simplicity ratios :-)
> 

Sounds good to me then.

-Kyle

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

2010-08-05 Thread Kyle Schaffrick
On Thu, 5 Aug 2010 16:05:07 +0200
Laurent PETIT  wrote:
>
> My point was that by providing different interfaces/protocols to
> different "users", it's more an implementation detail than anything
> else if they have the same object or not.  I don't expect my users to
> program on types, but on protocols/interfaces.
> 
> (ok, in this case, i'm my own user, so I have indeed some expectations
> on me ;) )
> 
> 
> > > After all I was wrong, it's not a delayed delay I've written.
> > > How to rename things ?
> > >
> > > timed-delay ->  ?
> > > delay.util.Cancellable ->  ?
> > > isCancelled -> ?
> > > cancel -> ?
> >
> > timed-delay -> ok
> > Cancellable -> Timed
> > isCancelled -> countdown-stopped?
> > cancel -> stop-countdown
> >
> > Maybe like this? I dunno. I'm bad at names. :]
> >
> >
> Hm, well .. let's say not worse than me :)
>

It sounds like you're having trouble defining what the primitives of
your interface are. If I may attempt it, I'll call this construct an
"idle speculative cache", i.e. you want to speculatively cache the
evaluation some potentially expensive function over an input at a time
when the input's value is not changing in a volatile manner, thus
avoiding repeatedly and rapidly invalidating cached results of a
potentially expensive operation.

I can identify three or possibly four useful primitives on an idle
speculative cache:

  (create-isc f timeout inital-input)
  (update-input! isc x)
  (deref isc)

 * 'create returns some opaque thing representing the evaluator, given
   the function it is to evaluate, the idle timeout for speculative
   evaluation, and the initial input value.
 * 'update-input! updates the input value and resets the timeout.
 * 'deref gets the output value, forcing an evaluation if the cached
   output is out of date.

You might optionally implement another primitive for inspecting the
state that does not force, that can either retrieve a possibly-stale
result, or retrieve a fresh result and fail if it would require forcing.

Given that interface, here's one implementation I came up with:


  (defn- update-cache [isc]
(let [input  @(:input isc)
  new-output-val ((:func isc) (:val input))
  new-output {:val new-output-val :ts (:ts input)}]
  (reset! (:output isc) new-output)
  new-output-val))

  (defn- isc-runner [_ isc]
(let [input  @(:input isc)
  quiescent-time (- (System/currentTimeMillis) (:ts input))
  sleep-to-go(- (:timeout isc) quiescent-time)]
  (if (pos? sleep-to-go)
(do (Thread/sleep sleep-to-go) (recur nil isc))
(do (update-cache isc) false

  (defn- deref-isc [isc]
(let [output @(:output isc)]
  (if (= (:ts @(:input isc))
 (:ts output))
(:val output)
(update-cache isc

  (defrecord IdleSpeculativeCache [func input output timeout runner]
clojure.lang.IDeref
  (deref [isc] (deref-isc isc)))

  (defn update-input! [isc x]
(reset! (:input isc) {:val x :ts (System/currentTimeMillis)})
(when (not @(:runner isc))
  (send-off (:runner isc) (constantly true))
  (send-off (:runner isc) isc-runner isc)) nil)

  (defn create-isc [f in to]
(let [isc (IdleSpeculativeCache.
f
(atom {:val nil :ts 0})
(atom {:val nil :ts 0})
to
(agent false))]
  (update-input! isc in)
  isc))


This one has one bug I know of, which is that the speculative
evaluator ('runner which monitors the i.s.c. input activity) does not
check if the output is already fresh due to 'deref forcing before
re-evaluating, but I think that could be fixed easily with a test in
update-cache.

I hope it helps,  :)

-Kyle

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

2010-08-04 Thread Kyle Schaffrick
On Wed, 4 Aug 2010 14:58:46 -0400
Andrew Boekhoff  wrote:

> Hi,
> 
> > because the symbol's namespace is then nil, and you still can't
> > tell if they're shadowing it with a let binding, or have renamed it
> > with :as.
> > 
> 
>   If the namespace is nil then its either been :used or :required.
> You could check ns-refers to see if its been :used. If its been
> shadowed the symbol will appear in &env. But, as you suggested,
> checking for the var may be easier and sufficient as well. 

I think this is the way I will go. I came across &env earlier today and
that gave me some ideas, although I don't know if I need to get that
complex. Maybe it is sufficient to have the assumption it will always be
a straightforward call where they use the symbol as it appears in their
namespace. So long as I can identify that, I think it will be
sufficient.

>   That said, neither method is really composable. If the symbol
> usually represents a normal function, the user may wrap it in a
> helper or otherwise use it in a way that the symbol is not visible.
> In that case a macro will never be able to find it.

If they do that then I'd actually prefer the macro not attempt to
transform it, because the semantics would be ill-defined, so this is
actually perfect.

All I'm after is to allow the user to be able to control my library's
effect on his/her namespace in the ordinary manner, and still let my
macro be able to identify calls to that function in a reasonably robust
way.  Since the function, used outside the macro, is actually useful in
and of itself, having it be unnecesarily assymetrical (called one thing
in the macro and another thing outside it) is something I'd like to
avoid.

Thanks for your thoughts.

-Kyle

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

2010-08-03 Thread Kyle Schaffrick
On Mon, 2 Aug 2010 07:23:12 -0400
Andrew Boekhoff  wrote:
>
> On Sunday 01 August 2010 21:34:16 Kyle Schaffrick wrote:
>
> > Hello,
> > 
> > I'm trying to write a library with two main parts. The first is a
> > macro, I'll call it 'with-feature, that walks through forms passed
> > inside it, and any time it sees a call to another function in my
> > library, 'feature, do some transformations.
> > 
> > The problem I'm concerned about is as follows: When my macro sees
> > the forms that are passed into it, the symbols come in however the
> > consumer of the library wrote them. So say I :require my library and
> > alias it to 'mylib', then the call 'with-feature is looking for
> > appears as 'mylib/feature. Or, I could :use the library, and then it
> > would appear as 'feature, or I could alias 'feature to 'banana--you
> > get the idea.
> > 
> > I don't want to reserve some magic symbol name that defies namespace
> > rules, so that if the library consumer code uses the symbol 'feature
> > to mean something different, they get bizarre results.
> > 
> > What is a good pattern for writing the "matching" logic in such a
> > selectively-transforming macro so that it can properly find the
> > magic call it's looking for in the presence of normal namespacing
> > behavior?
> > 
> > Thanks,
> > 
> > -Kyle
> 
> 
> Hi,
>   The following technique seems to work for finding out if you've
> been aliased:
> 
> (ns somewhere.trial)
> 
> (let [here *ns*]
>   (defmacro whats-my-name []
>  (some (fn [[k v]] (when (= here v) `(quote ~k)))
> (ns-aliases *ns*
> 
> user> (require '[somewhere.trial :as aliased]) => 
> user> (aliased/whats-my-name) => aliased
> 
> So at the top of with-feature the parser could check for an alias and
> construct the appropriate predicate from the result.
> 
> -Andy
> 

I originally had something similar to this actually, but it doesn't work
for the case when the library is referred in the consumer code with :use
because the symbol's namespace is then nil, and you still can't tell if
they're shadowing it with a let binding, or have renamed it with :as.

However, this idea occurred to me yesterday. What if I check to see if
the symbol is pointing to the *var* containing my magic function,
instead of trying to examine the symbol itself? e.g.:

  (= (resolve symbol-i-am-scanning-in-my-macro)
 #'function-i-am-looking-for)

It seems to work, since at macro-expand time *ns* is bound to the
consumer code's namespace. Does this seem like a reasonable way to deal
with this?

-Kyle

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


Symbol substitution in macro

2010-08-01 Thread Kyle Schaffrick
Hello,

I'm trying to write a library with two main parts. The first is a
macro, I'll call it 'with-feature, that walks through forms passed
inside it, and any time it sees a call to another function in my
library, 'feature, do some transformations.

The problem I'm concerned about is as follows: When my macro sees the
forms that are passed into it, the symbols come in however the consumer
of the library wrote them. So say I :require my library and alias it to
'mylib', then the call 'with-feature is looking for appears as
'mylib/feature. Or, I could :use the library, and then it would appear
as 'feature, or I could alias 'feature to 'banana--you get the idea.

I don't want to reserve some magic symbol name that defies namespace
rules, so that if the library consumer code uses the symbol 'feature
to mean something different, they get bizarre results.

What is a good pattern for writing the "matching" logic in such a
selectively-transforming macro so that it can properly find the magic
call it's looking for in the presence of normal namespacing behavior?

Thanks,

-Kyle

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

2010-07-30 Thread Kyle Schaffrick
On Fri, 30 Jul 2010 10:09:42 +0200
Meikel Brandmeyer  wrote:

> Hi,
> 
> Am 30.07.2010 um 04:53 schrieb Kyle Schaffrick:
> 
> > Is there some reason the 2.2.0-SNAPSHOT's of vimclojure have
> > vanished from Clojars? I have the 2.2.0 vim pieces in my .vim
> > directory and the nailgun commands blow up when using the jar of
> > nails from the 2.1.2 release :(
> > 
> > Would be hesitant to spend half an hour to clean out the 2.2.0
> > snapshot of the vim files and install 2.1.2 if I didn't have to,
> > since although I was able to manually install the snapshot, I'd
> > prefer to let Lein do it's thing.
> 
> There were never official SNAPSHOTs on clojars. Someone hijacked (I
> suppose by accident) the vimclojure group id.
> 
> I will provide a reasonable working snapshot this weekend. You can
> take your previous snapshot (I suppose leiningen caches it somewhere)
> and put it manually into the lib directory. This might work as a
> workaround to bridge the time till then, but I’m not sure how
> leiningen reacts on that.
> 
> Sincerely
> Meikel
> 

Thanks Meikel. I suspected that might have been what happened. I
managed to make Lein happy by sticking the previous snapshot from one
of my VMs in the appropriate place in ~/.m2/repository and everything
seemed to work again for now. Not sure what will happen when it decides
that the snapshot is out of date :)

Looking forward to the next release, 2.2.0 fixes a lot of little issues
I was having with the older versions, in particular dealing gracefully
with things going wrong. The only remaining issue I've had is if you
open a .clj file in Vim before you've started the Nailgun server, there
seems to be no way to tell VimClojure to "try again" to connect to NG,
it just latches into the "could not connect to Nailgun" state, which
seems to require a complete restart of Vim to "reset" it. Other than
that it works beautifully.

Anyway, between Leiningen, lein-nailgun, and VimClojure, getting a
Clojure development environment set up is an absolute breeze compared
to (say) 3 months ago! Thanks a lot for your (and Phil and brandonw's)
great work!

-Kyle

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


VimClojure 2.2.0 snapshot missing?

2010-07-29 Thread Kyle Schaffrick
Is there some reason the 2.2.0-SNAPSHOT's of vimclojure have vanished
from Clojars? I have the 2.2.0 vim pieces in my .vim directory and the
nailgun commands blow up when using the jar of nails from the 2.1.2
release :(

Would be hesitant to spend half an hour to clean out the 2.2.0
snapshot of the vim files and install 2.1.2 if I didn't have to, since
although I was able to manually install the snapshot, I'd prefer to let
Lein do it's thing.

-Kyle

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

2010-07-18 Thread Kyle Schaffrick
On Sat, 17 Jul 2010 00:59:35 -0700 (PDT)
Quzanti  wrote:

> Thanks Michał
> 
> I suppose this raises a deeper question - should an expression and
> what it evaluates to always be interchangeable in source code?

This is essentially what I was trying to say, stated much more
clearly :)

> On Jul 17, 2:18 am, Michał Marczyk  wrote:
> > This is an instance of the broader issue whereby records currently
> > evaluate to maps. There was a ticket open for that on Assembla. I'm
> > not sure what's the current status on that, but whenever it gets
> > fixed, macros will be able to use records in their expansions.
> >

I was asking about other things as well besides records, like Java
objects or fn's or other objects that the reader would never emit, but
that a macro conceivably could. Is it specified behavior (modulo the
"records evaluate as maps" bug) that *anything* that isn't a list or
symbol evaluates to itself if it appears in a macro-expansion or is
otherwise eval'ed?

Here's an example that doesn't work, but should by this hypothetical
evaluate-to-self rule which I just made up. Bug, unspecified behavior,
or have I just made a mistake?

  ;; Regular run-of-the-mill macro, works fine. Expansion only contains
  ;; things that can be read.

  user=> (defmacro list-of-list [action]
   `(println (~action)))
  #'user/list-of-list
  user=> (macroexpand '(list-of-list (constantly 1)))
  (clojure.core/println ((constantly 1)))
  user=> (list-of-list (constantly 1))
  1
  nil

  ;; Martian macro. Note the expansion contains the actual fn instead
  ;; of the expression that creates it. The reader would never output
  ;; such a construction.

  user=> (defmacro list-of-fn [action]
   `(println (~(eval action
  #'user/list-of-fn
  user=> (macroexpand '(list-of-fn (constantly 1)))
  (clojure.core/println (#))
  user=> (list-of-fn (constantly 1))
  #

-Kyle

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

2010-07-15 Thread Kyle Schaffrick
On Thu, 15 Jul 2010 23:08:27 -0700 (PDT)
Quzanti  wrote:

> Kyle
> 
> I think I understand what you are saying.
> 
> So in practice you should prevent functions called from a macro from
> evaluating the records (using quoting), so that the output is in a
> form that looks like source code should?
> 

Precisely; I think my first instinct would be that macros should
probably only expand to forms that look like regular Clojure source.

However there are situations where it is appropriate and indeed very
useful to unquote function calls in a macro. For example you may wish to
call some regular function that returns a data structure which you then
insert into the macro expansion. Personally I find this is actually
a very useful technique for writing macros: write a regular, private
function that does the "hard work" of transforming the source code data
structures without having to worry about macros' "abnormal" evaluation
rules, and then call that function from a much simpler macro, inserting
the result in the macro expansion using unquote.

However, I would think any data structure returned from a function used
in this way would still need to be something that can be interpreted as
Clojure source code: lists, vectors, maps, and sets containing symbols,
keywords, and so on. Any sort of user defined objects or Java objects,
*as far as I can tell*, don't make any sense in the result of a macro
expansion, but that is why I wrote this part:

> > What I don't know is, is it meaningful for a macro to expand to
> > something that contains stuff that couldn't ever appear in the
> > output of the reader, like instances of user-defined types, or even
> > Java objects for that matter? What is the expected behavior here?
> >

This was actually sort of an open question to the Clojure experts on the
mailing list, since I'm not actually sure about the answer. Should
this be done at all? Is it always an error (or at least bad style), or
should/could it be a meaningful operation in some cases? As I said, I
don't see any useful reason to do this, but maybe I just can't think of
one. I'd be interested to know what others think.

-Kyle

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

2010-07-15 Thread Kyle Schaffrick
On Thu, 15 Jul 2010 08:10:55 -0700 (PDT)
Quzanti  wrote:

> Hi
> 
> Here is my sorry tale
> 
> http://gist.github.com/477069
> 
> I am not sure if this could be my misunderstanding of macros or the ~
> idiom
> 
> Anyway if you spell out a record structure to a macro then you keep
> the Record information, even you call a function which spells out the
> structure then the records get turned into PersistentArrayMaps?
> 
> I first discovered this behaviour on an early July build, but it is
> the same in the 1.2 Beta
> 
> Any clues?
> 

I think I see the problem.

In the first case, the ~ (unquote) is causing the result of evaluating
the (company-fn) (which is a record) to be inserted at macro expansion
time. Since defrecord's implement IPersistentMap, it appears to get
converted to literal maps in the result of the macro expansion. Then,
when you *evaluate* the result of the macro expansion, the literal map
evaluates to itself and gets returned as a plain old map.

In the direct case (explicit-var), you're not inserting a record into
the macro expansion, but rather a form for constructing one, because
it's not unquoted. Then, when that is evaluated *after* macro expansion
time, it constructs the record instance. The key insight is that
(Company. ...) is not actually a "literal" record, it's a call to a
constructor, which like all function calls, is a list.

In essence, var-from-fn constructs the record (which is converted to a
map literal) at *macro expansion* time, while the second one constructs
the record at *evaluation* time. If you force evaluation of the
(Company. ... ) form at expansion time by unquoting it in explicit-var,
I imagine they will both return regular old maps via the same quirky
conversion behavior.

What I don't know is, is it meaningful for a macro to expand to
something that contains stuff that couldn't ever appear in the output
of the reader, like instances of user-defined types, or even Java
objects for that matter? What is the expected behavior here?

To me it seems like that the behavior it exhibits here is an
implementation artifact.

-Kyle

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

2010-07-13 Thread Kyle Schaffrick
On Mon, 12 Jul 2010 02:06:05 -0700 (PDT)
Krukow  wrote:
> 
> On Jul 11, 11:55 am, stewart  wrote:
> > Hi All,
> >
> > Has anybody considered implementing Clojure on BEAM. Are there any
> > works or current attempts currently available?
> >
> > In your view where are the real trip ups for this to happen.

I looked into targeting a language to BEAM, and honestly the biggest
obstruction for me at that time was that BEAM's bytecodes were (are
currently?) not documented really at all. Maybe efforts like LFE (Lisp
Flavoured Erlang) and Reia will change that as other people become
interested in targeting their languages at BEAM.

Currently I *believe* Reia is implemented as a cross-compiler, emitting
Erlang source and immediately compiling it with the compile module,
which completely sidesteps that issue. Someone else (Robert Virding?)
would have to speak for LFE's compiler. It probably emits beamfiles
directly but since I believe Robert, you know, wrote large portions of
the emulator, he probably does not require a bytecode reference. :)

Other obstacles I can see: 

* Implementing Clojure's shared-memory primitives like refs, agents,
  atoms on BEAM which AFAIK fairly strictly enforces shared-nothing.

  If one is willing to write Clojure in a non-shared-memory,
  Erlang-like style, they may simply opt to discard them, or substitute
  some sort of Clojure-flavored actor primitives to embrace the
  message-passing style of Erlang. This would not bother me that much
  (see [1]), but many others would argue it's not Clojure anymore and
  that you might as well use LFE.

  Or, alternatively, one might investigate using ETS or Mnesia memory
  tables for "shared memory", the latter already having transactional
  semantics. The fact that Clojure explicitly demarcates shared state
  makes this, on it's face, seem imminently doable, although likely
  with lots of performance red flags.

* Data structures. BEAM does not have a native map or vector, let alone
  persistent ones, and ones written in Erlang/Clojure are likely to be
  slow. On the plus side, the data structures you do get (list and
  tuple) are already immutable, so no "this thing from Java-land might
  be mutable" wierdness that can occasionally happen on the JVM/CLR.
  Still, this could be a deal-breaker, I think, unless someone
  smarter than I am sees a good way to fit the data types together
  (again, see [1]).

All that said, Clojure-in-Clojure (when it arrives) would make such an
effort a lot easier. I'd wait for that even if I already had my mind set
on porting Clojure.

> 
> Instead you should take a look at Erjang
> 
> /karl
> 

My personal opinion was always that the BEAM emulator and it's process
model was the really compelling part of Erlang, less so the language
itself, so a JVM implementation of the Erlang language never seemed
that interesting to me. But I have to admit, the performance numbers
Erjang is posting took me completely by surprise. A stroke of
brilliance using Kilim for the scheduler; I think my previous
indifference assumed a naive JVM Erlang implementation that mapped
processes onto Java threads and, you know, sucked.

That said, I still think BEAM is pretty dang cool, and I continue to
quietly root for implementers trying to target other languages to it.

-Kyle

[1] Clojure's appeal, for me, comes 95% from the fact that it's a lisp
that has sane data structures as *first class members of the
language*. Everything else, including a lot of what people like to
brag about in Clojure like STM and being on the JVM, is icing as
far as I'm concerned. I tried to learn Common Lisp, but when I
found out that something as simple as a vector or a hash map was a
second-rate data structure, I lost interest and went back to
Python. Data structure seamlessness is frankly worth more to me
than macros, because I need a vector or a hash map 100x more often
than I need a macro. :)

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

2009-10-28 Thread Kyle Schaffrick

Don't forget those of us who dislike web-forum software and prefer to
interact with the group via email: I very seldom use the GG site itself.
I find threaded email is a *very* good way of following discussions. I
can have a "I didn't know that" moment delivered to my inbox every day,
without having to visit a website and contend with the interface of
yet-another-web-forum.

On Wed, 28 Oct 2009 10:22:04 -0700 (PDT)
offwhite  wrote:
> 
> I think John made some very good points in that blog post.
> 
> I am running a Google Group and I am finding for smaller groups it is
> possible to give a few people moderator rights so that any new members
> are able to get their posts in at a reasonable time. Still, the points
> that John raises are valid.

I don't think spam control is any more difficult on mailing lists than
it is in general, it just seems that GG in particular sucks at it. GG's
problems aren't a condemnation of mailing lists in general, just GG's
implementation in particular. I subscribe to many other MLs not on GG
and they have zero spam problems.

Also, the user experience is "meh" at best, and the GG search is
surprisingly and ironically crappy. You get better results by picking
markmail or nabble results out of a google web search than by trying to
search google groups directly.

> 
> I suggested that he do the following.
> 
> 1) Shut down posting from non-admins for the group ( limit to
> announcements and summaries )
> 2) Direct people to ask questions on StackOverflow.com (SO) and tag
> the questions appropriately (jQuery in John's case, Clojure for this
> group)
> 3) Aggregate all new questions on SO regularly (every 4 hours?) to
> create a summary post on this group
> 
> A group is useful because it gives you a central place to keep
> everyone up to date by sending out announcements. Since spam can get
> through when they are mixing in with a large number of members who
> have rights to post messages it seems Google Groups has a problem with
> preventing spam. So this hybrid approach may be the best option for
> now. I have found that SO is a great solution for getting quick
> answers which tend to be good quality answers. Their who system for
> rating answers and awarding community points has been working very
> well. There is no such thing for Google Groups.
> 

SO (by design) forces the interaction into a "question and answer"
format, so is ill-suited for general discussion, which is part of the
reason I enjoy following mailing lists like this one. The pontificating
is equally if not more interesting than the question-and-answer threads
on here, particularly with as high caliber as the community around
Clojure seems to be.

I really like SO precisely because it sidesteps a lot of problems with
traditional web fora, but attempting to use it to *replace* a mailing
list is, I think, ill-advised.

> On the flip side, there is no way to indicate group membership with
> Clojure or jQuery on SO that I know about. Being able to send out an
> announcement to a group that is "following" a tag could be a way to
> eliminate a need for Google Groups altogether. I do not know if this
> is on the SO feature list.
> 

Would definitely be nice, I would end up on SO a lot more often if it
had email-enabled "nosy" lists.

> Brennan
> 

-Kyle

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

2009-06-23 Thread Kyle Schaffrick

On Tue, 23 Jun 2009 21:35:33 +0200
Laurent PETIT  wrote:

> 
> I like reptile, and also Corona for the meaning it conveys, a lot !
> 

I like "Corona" as well. It lends itself nicely to some kind of visual
pun involving a partial eclipse and a parenthesis :)

-Kyle

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

2009-06-23 Thread Kyle Schaffrick

On Tue, 23 Jun 2009 18:23:01 +0200
Christophe Grand  wrote:

> I think you could simplify your code by using map twice. What about:
> (untested)
> 
>  (defn weighted-moving-average
>"Generate a lazy sequence consisting of weighted moving averages
>over the input sequence. The weighting is given by weight-fn,
> having a domain 0..1 which will be scaled across win-size elements to
>calculate the weighting."
>[weight-fn win-size input]
>(let [weights (reverse (for [t (range 1 (inc win-size))]
>(weight-fn (/ t win-size
>   weight-sum (reduce + weights)
>   normalized-weights (map #(/ % weight-sum) weights)
>   avg #(reduce + (map * normalized-weights %))]
>  (map avg (partition win-size 1 input

Hmm, yes that is certainly simpler. 

This actually reminds me of something that I've "felt" for awhile but
haven't been able to articulate: A lot of functional programming
literature takes great pains to explain how higher-order functions,
lambda expressions, closures, etc work, and so I feel like I have a
fairly solid grasp of the mechanics of many functional concepts. I could
probably even give you a passable explanation for how to implement
lexical scoping.

But, I still sometimes find it challenging to spot patterns that can be
replaced and simplified with HOFs and other functional idioms, and I
haven't come across any books/guides that help hone one's intuition for
doing this. This is a good example because, while I have no trouble at
all understanding your implementation, I doubt I would have ever thought
of it myself!

I wonder if anyone has a guide or tips or rules of thumb to help with
this, or if it just takes experience...

As an aside, I also notice you prefer 'reduce to 'apply when using
arithmetic functions, yet I've seen both in the wild. I'm just guessing
you prefer to make it explicit that you're doing a reduction, but I
wonder if one is better than another?

> 
> btw, why the 'reverse in weights?
> 

I found it makes it easier to think about the weighting function if
(weight-fn 0) evaluates to the weight of the most recent sample (the
latest in the sequence), but the 'for comprehension generates them with
(weight-fn 0) as the first element in the sequence.

I suppose, it would be more efficient to have 'range generate the series
in reverse to begin with, wouldn't it? :)

-Kyle

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

2009-06-23 Thread Kyle Schaffrick

On Tue, 23 Jun 2009 10:20:52 -0400
Kyle Schaffrick  wrote:
> 
> On Mon, 22 Jun 2009 23:36:25 -0700 (PDT), Sean Devlin
>  wrote:
> > Hey all,
> > Does anyone know of a moving window function?  I'm curious if there
> > are any tools like this for digital signals processing, 30-day
> > moving averages, etc.
> 
> If you need weighted moving averages, this is a tad ugly but seems to
> work ..
> 

Okay it is still a tad ugly but hopefully now it won't be because
the blasted mail client mutilated it :)

  (defn weighted-moving-average*
"Generate a lazy sequence consisting of weighted moving averages
over the pre-partitioned input sequence. The weights parameter
should be a sequence of weights the same length as the partition
size."
[weights input]
(lazy-seq
  (when-let [input (seq input)]
(let [weight-sum (apply + weights)
  weighted-input-sum (apply + (map * weights
 (first input)))]
  (cons (/ weighted-input-sum weight-sum)
(weighted-moving-average* weights (rest input)))

  (defn weighted-moving-average
"Generate a lazy sequence consisting of weighted moving averages
over the input sequence. The weighting is given by weight-fn, having
a domain 0..1 which will be scaled across win-size elements to
calculate the weighting."
[weight-fn win-size input]
(let [weight-samples (reverse (for [t (range 1 (inc win-size))]
(/ t win-size)))
  weights(map weight-fn weight-samples)]
  (weighted-moving-average*
weights (partition win-size 1 input

> 
> -Kyle
> 
> 

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

2009-06-23 Thread Kyle Schaffrick

On Mon, 22 Jun 2009 23:36:25 -0700 (PDT), Sean Devlin
 wrote:
> Hey all,
> Does anyone know of a moving window function?  I'm curious if there
> are any tools like this for digital signals processing, 30-day moving
> averages, etc.

If you need weighted moving averages, this is a tad ugly but seems to
work ..

(defn weighted-moving-average*
"Generate a lazy sequence consisting of weighted moving averages
over the pre-partitioned input sequence. The weights parameter
should be a sequence of weights the same length as the partition
size."
[weights input]
(lazy-seq
(when-let [input (seq input)]
(let [weight-sum (apply + weights)
weighted-input-sum (apply + (map * weights (first input)))]
(cons (/ weighted-input-sum weight-sum)
(weighted-moving-average* weights (rest input)))

(defn weighted-moving-average
"Generate a lazy sequence consisting of weighted moving averages
over the input sequence. The weighting is given by weight-fn, having
a domain 0..1 which will be scaled across win-size elements to
calculate the weighting."
[weight-fn win-size input]
(let [weight-samples (reverse (for [t (range 1 (inc win-size))]
(/ t win-size)))
weights(map weight-fn weight-samples)]
(weighted-moving-average*
weights (partition win-size 1 input

-Kyle


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

2009-06-22 Thread Kyle Schaffrick

On Sun, 21 Jun 2009 14:39:37 +0100, Jon Harrop 
wrote:
> 
> I had not looked at Intel's offering because it does not (AFAIK) support 
> accurate garbage collection. Also, it is worth noting that there is no 
> difference between data and task parallelism in a genuine functional 
> language.
> 

Well, I meant task parallelism vs. data parallelism in the design
intent, rather than the implementation. I find that calling
computational fluid dynamics "data parallel", and a telecom switch "task
parallel" is useful even if happens that solutions to both sorts of
problems in "genuine FP" are somehow isomorphic. I feel that's because
the problem domains, and the ways a typical programmer thinks about the
solutions, are different enough that the isomorphism isn't likely to be
astonishingly useful in practice. Well, maybe except for programming in
the small.

For instance, I don't see overwhelming practical applications of proving
one could implement a telecom switch as parallel maps and reductions
over a bunch of functions, unless (perhaps) you're a compiler writer
and/or designing a DSL for the purpose. It's fun as a thought
experiment, but I think that it would stray too far from the language of
the problem without lots of sugar that would (it seems to me) just sort
of take you back to where you started in terms of expressiveness.

But then again, those sorts of visions aren't my forte :)

> Right. If you hand-roll your C++ very carefully then you can get decent 
> performance but I was disappointed with the performance of the template 
> libraries and quality of g++ back in 2004 and have never used C++ since.

Yeah, g++ 4.1 and 4.2 seemed to have a reputation for being especially
bad at optimizing away abstraction penalties of heavy template usage. I
understand this is much better in recent releases, but I haven't
measured it myself.

For all it's warts, C++ (like Java) has interesting things happen to it
here and there, if only by sheer volume and chance. And every so often a
problem comes along that feels like a good fit.

Maybe I'm just perverse, and I bet *nobody* here will agree with me, but
sometimes I feel "wrong" when I use a language like a Lisp, with its
symbolic and meta-everything sweet spot, to do something as brutish and
mundane as picking apart awful binary formats and chewing through
vectors of integers and floats. It feels like ruining expensive top
shelf bourbon by pouring it in Coke :)

-Kyle


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

2009-06-20 Thread Kyle Schaffrick

On Sat, 20 Jun 2009 11:29:44 +0100
Jon Harrop  wrote:
> 
> On Saturday 20 June 2009 08:34:39 Konrad Hinsen wrote:
> > What't TPL?
> 
> The Task Parallel Library. It uses concurrent wait-free work-stealing
> queues to provide an efficient implementation of "work items" than
> can spawn other work items with automatic load balancing on shared
> memory machines. Cilk uses the same technology (well worth a look if
> you haven't already seen it!). That makes it easy to write efficient
> parallel algorithms in any .NET language. In particular, it can
> sustain billions of work items (as opposed to thousands of threads or
> processes) and the time taken to spawn is ~30,000x faster than
> forking a process. Extremely useful stuff!
> 

Interesting. It strikes me that it's called "task" parallel library,
while it sounds a lot like Intel Threading Building Blocks, which is a
sort of STL-style quasi-functional template library for *data*-parallel
algorithms; the stuff people like to write with Fortran, OpenMP and
friends.

It uses a work-stealing thread-pool scheduler as well, atop which stuff
like parallel maps and reductions are implemented as templates. You can
create your own work items and stick them in the scheduler by hand, but
the useful bits are actually the prefab algorithms, IMO.

The tunable/pluggable "slicing" strategies, built on the standard
iterator concepts, are particularly interesting way to give you full
control of work unit granularity, without having to know too much about
the innards of the algorithms themselves.

-Kyle

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

2009-06-17 Thread Kyle Schaffrick

On Wed, 17 Jun 2009 10:51:48 -0700 (PDT),
Wrexsoul  wrote:
> On Jun 17, 3:20 am, kkw  wrote:
>> I only knew about map, apply, and reduce from studying haskell in uni.
>> I've not heard of 'reduce' referred to as 'accum', but then again when
>> I wanted to determine the number of elements in a seq, I kept
>> searching for 'length' and 'size' but didn't think of 'count', so it
>> can be a bit tricky eh?
> 
> Guess-the-synonym -- fun for the entire family! But I looked not only
> for "accumulate" or similarly but when I didn't see it, for every
> single function whose documentation mentioned "seq", figuring that
> should cover everything taking a sequence as input.

For reference, Wikipedia offers "accumulate", "compress", "inject", and
"foldr"/"fold-right" as common synonyms for reduce.  Similarly "collect"
and "transform" for map. Perhaps these words should appear in the
docstrings just for searching purposes?

> 
>> I've certainly asked my fair share of noob-
>> questions, and folks in this group have been quite happy to oblige me.
> 
> Yes; it seems the derision comes when you don't find something and
> then instead of asking after it here you actually implement it
> yourself. :) This is rather odd -- normally, self-help should be
> rewarded in preference to always bugging the forum for assistance, not
> punished. Sharing your efforts that might benefit others, likewise.
> 

As a friendly suggestion, I'd like to offer that perhaps the derision is
caused not by the fact that you had the initiative to implement it
yourself, but rather by such phrasing as:

> I'm shocked that [reduce/accum/foldr] is missing from clojure.core.
> [...] This is one of the most basic, useful functions in functional
> programming.

This seems to assert *as fact* that it is missing, fails to acknowledge
the possibility that (either by accident or by documentation that could
be more comprehensive) you simply overlooked it, and perhaps worst of
all, suggests incompetence on the developers' part for excluding it.

There are many extremely smart people, far smarter than I am, working on
Clojure and participating in this mailing list. When in doubt, I invoke
maximum humility, because I am usually wrong :)

-Kyle


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

2009-06-09 Thread Kyle Schaffrick

On Fri, 5 Jun 2009 02:18:53 -0700 (PDT)
Robert Lehr  wrote:
> 
> The problem was that it was not as fast as I expected it should be
> given that it was using no less than 100% of the CPU on my system.
> (two 3GHz Xeon CPUs [1 core]; 3GB RAM; a beefy workstation).  That
> this was visible in the GUI shows how slow it appeared to me.  Also,
> it was using 700MB RAM (VIRT in top).  Sure - it was "swapped" (I'm
> familiar w/ some of the interpretations of these memory issues) except
> that my system has ZERO swap space.  PMAP showed that 400MB of it was
> heap, too, not libraries or binaries or anything else that we can
> safely ignore.  This was (apparently) real, allocated heap, private to
> the process's address space.
> 
> Additionally, as the simulation ran, the initial RSS of 60MB rose to
> 130MB then stopped.  The VIRT remained constant.  I had expected that
> - however I remained concerned.
> 

Just wanted to add some personal notes about the VMM behavior of Linux
in particular that I've observed while tinkering with JVM and PyPy's
garbage collectors and allocators.

Regarding the VIRT and SWAP numbers, it should be noted that, on Linux,
VIRT is a rough estimate of the amount of virtual *address space* that
the process has actually allocated. Not all of this address space
necessarily has corresponding storage on RAM or swap. The reason
revolves mostly around mmap().

Large allocations (of the sort that GC arenas and pool allocators
typically make) are usually serviced by mmap(), which is very lazy in
Linux.

As it has been described to me, what this means is that in the kernel
there is a reserved "dummy" physical page that's filled with zeros that
all pages in the newly allocated virtual address space are mapped to.
When the application actually faults in the page, only then is it
actually allocated in physical memory by the kernel.

The kernel also "resets" a page into this lazy state (deallocating its
physical memory) when a process copies /dev/zero into it. Many
applications incorporate this knowledge so they can take advantage of
this lazy allocation behavior when running on Linux (several of PyPy's
allocators definitely do). I would be extremely surprised if the JVM
didn't do this as well, because it allows a process to "cheat" on RAM
usage by allocating a big arena of memory up front without actually
consuming that amount of RAM. Then, the app just uses the memory as
needed and lets the kernel/VMM worry about allocation.

The side effect of this is that stuff like top and ps report these
allocated-but-unbacked pages as "swapped" even though they aren't
actually on disk anywhere. When mmap() is used for loading real files
off the filesystem (also a lazy operation on Linux), I believe pages
of the file that have not been faulted into RAM are also reported as
swapped.

Executable images are AFAIK loaded by the kernel with mmap(), and large
images like the JVM almost certainly have many pages that may never be
faulted into RAM when running some kinds of apps. It would come as no
surprise to me if the JVM does some mmap()ing of portions of its own
runtime or other things that may also never get referenced.

As an aside, RSS (resident set size) is an estimate of the size of all
pages available to the process that are currently resident in RAM. This
area I am a little less clear on, but I *believe* this number is also a
bit inflated because it includes pages that are shared behind the scenes
from mmap()ed files.  What top reports as "shared" (I *think*) is
actually restricted to application-requested POSIX shared memory and
doesn't count mmap()'s copy-on-write, sharing-as-an-optimization shared
memory.

Sorry for the length, but I hope this may give some insight--hopefully
I'm not telling you things you already know :)

-Kyle

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

2009-04-21 Thread Kyle Schaffrick

On Mon, 20 Apr 2009 21:53:41 +0200
Laurent PETIT  wrote:

> 
> Hi David,
> 
> 2009/4/20 David Nolen :
> > A couple of things. In your initial example, you conflated some
> > things. One issue is simply a matter of convenience- defining a
> > getter so that you can use Python object property access (via the
> > dot operator). Personally I don't like this idiom at all (you find
> > it in Objective-C 2.0 and Javascript). It's simply syntactic sugar
> > that gets converted into another (hidden) form. Then support for
> > getters/setters is very much a "macro"-like trick, they will get
> > converted into the standard form somewhere.
> 
> I'm not sure if I understand correctly what you're saying here. Are
> you talking about this piece of code provided by Timo :
> 
> class Person2(object):
> first_name = "first"
> last_name = "last"
> 
> def get_name(self):
> return self.first_name + " " + self.last_name
> name = property(get_name)
> 
> , the get_name function ?
> 
> If so, then I think you may be wrong because get_name is not converted
> somewhere into boiler plate code. I rather think this is one of the
> dynamic strengthes of python being able to intercept calls on the fly.
> Different langage, different way of handling problems (no macros
> here).
> 
> Or is it really just syntactic sugar ?
> 
> Maybe I understand what you stated wrong, but I think here the
> syntactic sugar not only has the value of saving some characters (not
> having to type getName but just name), but also is an implementation
> example of what Bertrand Meyer calls "the principle of uniform access"
> in his "Object Oriented Software construction" book.
> 

I think this last point is the most important aspect of Python's
property/descriptor feature.

What may not be obvious about his example is that after creating this
getter and it's associated property, you don't have to change the
consumers of Person instances. This is because a property translates
assignments and references into calls to the getter and setter
respectively; one can continue to write

  print "Hello, " + some_person.name

and the getter is transparently called when the attribute reference is
evaluated. This means that you can create interfaces that start out
using direct attribute accesses, eliminating all trivial
getters/setters, without worrying that it will break your API if you
later change your mind.

> > Data encapsulation in Clojure is far less of an issue than it is
> > with most OO languages, as data is immutable anyway. Encapsulation
> > support in a language that that don't truly protect instance
> > variables is pretty pointless anyway as well as being overrated
> > IMO. For example, JavaScript has no such encapsulation, yet large
> > programs can be written/scripted with it (FireFox).
> > Again if you want the convenience of setters/getters write a macro
> > to save you some typing.

This is starting to stray a bit from the original topic of the post, but
I did want to point out that because Javascript provides closures, one
can implement enforced data hiding using an idiom that I picked up from
Douglas Crockford's "Javascript: The Good Parts". This thread has gotten
me thinking about whether this idiom could be adapted to (or inspire a
new idiom for) use in Clojure...

  function make_person(first_name, last_name) {
var private_member = something();

function private_function(x) {
  // do stuff
}

return {
name: function () {
  return first_name + ' ' + last_name;
},

public_function: function (a, b) {
  // do stuff
  return private_function(a + b);
}
};
  }

The return statement returns an object literal that contains the public
interface of a person, and any members inside it have access to private
data members and functions defined in the constructor's scope, by virtue
of closure. I had a new appreciation for Javascript after seeing it.

Of course, this doesn't really suggest a good way to solve the OP's
problem, but I thought it interesting in regards to the data hiding
aspects of this thread.

On the other hand, Javascript's unification of objects and maps (while
occasionally quirky) might point to a useful technique in Clojure, where
maps are promoted as perhaps *the* data structure of choice, in most
cases preferred to (for utter lack of a better term) "real" objects.

-Kyle

--~--~-~--~~~---~--~~
You 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: proposed new contrib: java-utils

2009-04-03 Thread Kyle Schaffrick

On Fri, 3 Apr 2009 10:17:33 -0400
Stuart Halloway  wrote:
> 
> Hi all,
> 
> I would like to pull together functions that help with Java interop  
> and place them in a new contrib: java-utils. Some examples:
> 
> [...]
> 
> If this is interesting to others (or at least inoffensive) I will
> move forward with it.
> 

I like it. Sounds like a "Clojure for people who don't know Java APIs"
layer. I'm in that group for the most part.

I do acknowledge and see the value in arguments against doing excessive
wrapping of Java-land, but at the same time, the Java libraries seem
quite baroque at times and can be difficult to understand for people who
haven't been steeped in Java idioms. Sometimes I find myself thinking,
"what on earth do I need to make all these objects for!?" (*cough* NIO
*cough*). But I must remind myself that perhaps such architectures solve
problems that I haven't had to deal with coming from other languages.
It's a tough issue.

> Are there other little nuggets of Java-interop code that I should
> also consider?
> 

I would love to see a non-blocking IO API that isn't psychotic. My brain
starts to liquify when I read the NIO API documentation, and from what I
can tell, even seasoned Java folks find it a bit much :)

-Kyle

--~--~-~--~~~---~--~~
You 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 print to standard output without using *out*?

2009-04-03 Thread Kyle Schaffrick

On Fri, 3 Apr 2009 07:20:39 -0700 (PDT)
Daniel Jomphe  wrote:
>
> Since I can't find the way to solve this issue, let's tackle it at a
> more fundamental level.
> 
> First, I need to make sure I can print to standard output without
> using *out*, so I can later, temporarily bind *out* to something else.
> Also, I don't want to print directly to System/out. Later, I'll need
> it to be wrapped into something that gives it a proper encoding.
> 
>   user=> (import '(java.io PrintWriter PrintStream))
>   nil
>   user=> (.print (PrintWriter. (PrintStream. System/out) true)
> "bonjour")
>   nil
> 
> Do you know how to make this work?
> 

I'm not sure if this is what you're asking, but...

Could you just make a new Var (like *always-stdout* or something) and
assign *out* to it at program start? This way the dynamic bindings on
*out* don't affect your new Var and you can continue using it to access
the "real" stdout.

I haven't tested this, just a suggestion :)

-Kyle

--~--~-~--~~~---~--~~
You 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
-~--~~~~--~~--~--~---



Bit-syntax (Was: Re: I need help tracking down a performance problem.)

2009-03-24 Thread Kyle Schaffrick

On Mon, 23 Mar 2009 19:41:07 -0700
Mark Engelberg  wrote:
> 
> On Mon, Mar 23, 2009 at 7:31 PM, Vincent Foley 
> wrote:
> > More generally, is it possible that I'm just doing this whole thing
> > wrong?  That using vectors to represent binary fields and records
> > in a declarative is just a bad idea and that I should try and
> > explore lower- level alternatives?
> >
> 
> 
> This reminds me... I would LOVE to see in Clojure something like
> Erlang's bit-packing/destructuring syntax for working with bit
> manipulation in a high-level way.
> 
> http://www.erlang.se/euc/00/bit_syntax.html
> 

I'm actually casually hacking on something like this right now, as I
want to attempt to port a radar processing code I wrote into Clojure.
(It's currently implemented in modern C++ with a functional-ish style)

The WSR-88D file format is *extremely* bizarre and convoluted and
requires a lot of bit-fiddling. Half or more of the current code is
dedicated to converting this format into something sane. I actually hate
that part of my C++ implementation the most because it's all
hand-written unpacking and endianness-fixing of byte arrays which seems
impossible to clean up any further.

-So- .. What I actually have so far is a macro that lets you basically
write Erlang bit-syntax in S-exps and it will expand into a vector that
you can use as the binding list of a let form. The IP header unpacking
example in Erlang's documentation looks something like this:

  (let (bits dgram 
 [ip-ver 4] [hdr-len 4] svc-type [tot-len 16]
 [id 16] [flags 3] [frag-off 13]
 ttl proto [hdr-cksum 16]
 [src-ip 32] [dst-ip 32] [rest-dgram :binary])
'stuff)

Not shown: floats, signedness, and endianness (defaults are all the same
as Erlang).

It's "okay", but it looks unnatural and I don't really like doing it
that way very much. The source and destination names are backwards
(dgram is being destructured into ip-ver, hdr-len and so on), and the
syntax hijacks the whole let form, because I don't think you can write a
macro that automatically splices into its parent form.

So I had been thinking of composing an email about what the likelihood
of seeing extensibility API for destructuring would be. The idea being
that the UI for the bit-syntax library would allow for this custom
destructuring to be pervasive, look a little more conventional, and let
you mix it with regular binding forms (instead of having to use an
explicit let that is completely hijacked by the bit-syntax).

You could of course write something that would unpack bits into a
vector, and then destructure the vector on the left-hand side, but that
separates the names which will be bound (on the left) from their field
specifiers (passed to the macro on the right). I found this difficult to
read when the specifier list gets large, so I implemented it this way so
the bound names are next to their specifications (just like Erlang's).

Details: the macro expands into a bunch of sequential let bindings that
progressively tease apart the blob using some helper functions. I
haven't actually implemented the functions that do this teasing yet
because that requires me to go digging in Java API docs to see what they
provide for dealing with bit-bashing, and I haven't had the inclination
to do that just yet :)

So, is there any chance of extensible destructuring? What would such an
API look like? I have thought about it a lot, but the minutiae of doing
this generally enough to be useful, but simple enough to be
implementable are probably beyond my grasp.

-Kyle

--~--~-~--~~~---~--~~
You 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: Bug in set?

2009-03-12 Thread Kyle Schaffrick

On Thu, 12 Mar 2009 15:50:16 -0700
Jason Wolfe  wrote:
> 
> On Mar 12, 2009, at 3:34 PM, Kyle Schaffrick wrote:
> 
> >
> > On Thu, 12 Mar 2009 12:45:00 -0700 (PDT)
> > Jason Wolfe  wrote:
> >>> Also, union/difference/intersection/symmetric-diff are binary.
> >>> Would there be any interest in a patch to make them n-ary?
> >>>
> >>
> >> Union, difference, and intersection are all variadic as of a month
> >> or so ago.  Are you on the latest SVN?
> >>
> >> -Jason
> >
> > Oops, so they are. I am actually on SVN but referred to (apparently)
> > out-of-date docs. That, or Rich has joined the circle of
> > time-machine-owning dynamic-language-designing BDFLs.
> >
> > In that case, here's my two stabs at n-ary set symmetric difference:
> >
> >  (defn symmetric-diff [& sets]
> >(let [all-members (apply union sets)
> >  nr-memberships
> >(fn [m] (apply + (for [s sets :when (contains? s m)] 1)))
> >  in-sym-diff (fn [m] (odd? (nr-memberships m)))]
> >  (set (filter in-sym-diff (seq all-members)
> >
> >  (defn symmetric-diff
> >([s1] s1)
> >([s1 s2]
> > (difference (union s1 s2)
> > (intersection s1 s2)))
> >([s1 s2 & sets]
> > (reduce symmetric-diff s1 (conj sets s2
> >
> > -Kyle
> 
> IIRC the docs all correspond to the last release, which was a couple  
> months ago.  This means that by now they are quite out of date, but
> at least they're stable for people who shy away from the bleeding
> edge.

Yeah, I always forget about that. *high-fives self*

> I suppose this might be good in clojure.contrib.set, if any of the  
> primary contributors want to OK it.  Have you done any timing
> tests? The first version could be improved by adding a "distinct" on
> all- members before the filter.

union does an implicit distinct operation, as it returns a set.  I
didn't think Clojure had multisets, unless we've had another Rich's Time
Machine moment :)

> My guess is that the second version would still be faster, but I'm not
> sure. Also, (union (difference s1 s2) (difference s2 s1)) may be
> faster than (difference (union s1 s2) (intersection s1 s2)), but again
> I'm not sure.

I generated 10 sets of 100 random integers between 0-200. Then I timed
3000 iterations applied to 1 thru 10 sets, on a -server VM. I warmed up
the JIT on each version a couple of times.

First version / second version:

 "Elapsed time: 462.881526 msecs"  "Elapsed time: 1.445784 msecs"   
 "Elapsed time: 901.305403 msecs"  "Elapsed time: 357.005849 msecs" 
 "Elapsed time: 1334.729903 msecs" "Elapsed time: 783.21756 msecs"  
 "Elapsed time: 1746.563041 msecs" "Elapsed time: 1165.418231 msecs"
 "Elapsed time: 2264.295812 msecs" "Elapsed time: 1549.46746 msecs" 
 "Elapsed time: 2569.731838 msecs" "Elapsed time: 1956.67962 msecs" 
 "Elapsed time: 2854.096121 msecs" "Elapsed time: 2349.644787 msecs"
 "Elapsed time: 3278.285648 msecs" "Elapsed time: 2768.575964 msecs"
 "Elapsed time: 3529.430695 msecs" "Elapsed time: 3136.699357 msecs"
 "Elapsed time: 3854.478292 msecs" "Elapsed time: 3514.263823 msecs"

It seems they're both linear complexity but the second is faster by a
noticeable constant. Fascinating!

-Kyle

--~--~-~--~~~---~--~~
You 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: VimClojure 2

2009-03-12 Thread Kyle Schaffrick

On Thu, 12 Mar 2009 13:30:51 -0700 (PDT)
Mark Volkmann  wrote:

> 
> On Mar 12, 3:21 pm, Mark Volkmann  wrote:
> > The README.txt file doesn't describe the files that need to be
> > copied to ~/.vim. I'm getting errors starting Vim now. I suspect
> > it's because I haven't copied all the necessary files to my ~/.vim
> > directory. Which files do I need to copy?
> 
> Here is the copy command I used:
> 
> cp -r {autoload,bin,doc,ftdetect,ftplugin,indent,syntax} ~/.vim
> 
> Here are the errors I'm getting.
> 
> Error detected while processing function
> vimclojure#ExecuteNailWithInput:
> line   23:
> E605: Exception not caught: Couldn't execute Nail! ng
> de.kotka.vimclojure.nails.N
> amespaceOfFile  v920635/0
> Error detected while processing /Users/Mark/.vim/ftplugin/clojure.vim:
> line  131:
> E171: Missing :endif
> Error detected while processing function 9_LoadFTPlugin:
> line   17:
> E170: Missing :endfor
> 

I got this exact error also at first. It turned out there was an
extraneous file in my .vim from an older version of Gorilla, pretty sure
it was ~/.vim/after/ftplugin/clojure.vim.

Deleting this file and restarting Vim fixed it for me.

-Kyle

--~--~-~--~~~---~--~~
You 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: VimClojure 2.0.0 released (merged with Gorilla)

2009-03-12 Thread Kyle Schaffrick

On Wed, 11 Mar 2009 00:36:39 +0100
Meikel Brandmeyer  wrote:

> Dear vimming Clojurians,
> 
> I'm proud to announce VimClojure 2.0!
> 

Working fantastic here, thanks for this. I just cannot get comfortable
in Emacs. I really did try :)

> 
> More information on the installation can be
> found in the README.txt.

Just as a side note, in said README you wrote:

| Put the nailgun client somewhere into your PATH or specify the
| location in your .vimrc.

but did not say how to do the latter. I figured it out, but had to dig
thru the clojure.vim file to figure out what variable to set. You might
want to mention it.

Thanks again!

-Kyle

--~--~-~--~~~---~--~~
You 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: Bug in set?

2009-03-12 Thread Kyle Schaffrick

On Thu, 12 Mar 2009 12:45:00 -0700 (PDT)
Jason Wolfe  wrote:
> > Also, union/difference/intersection/symmetric-diff are binary. Would
> > there be any interest in a patch to make them n-ary?
> >
> 
> Union, difference, and intersection are all variadic as of a month or
> so ago.  Are you on the latest SVN?
> 
> -Jason

Oops, so they are. I am actually on SVN but referred to (apparently)
out-of-date docs. That, or Rich has joined the circle of
time-machine-owning dynamic-language-designing BDFLs.

In that case, here's my two stabs at n-ary set symmetric difference:

  (defn symmetric-diff [& sets]
(let [all-members (apply union sets)
  nr-memberships
(fn [m] (apply + (for [s sets :when (contains? s m)] 1)))
  in-sym-diff (fn [m] (odd? (nr-memberships m)))]
  (set (filter in-sym-diff (seq all-members)

  (defn symmetric-diff
([s1] s1)
([s1 s2]
 (difference (union s1 s2)
 (intersection s1 s2)))
([s1 s2 & sets]
 (reduce symmetric-diff s1 (conj sets s2

-Kyle

--~--~-~--~~~---~--~~
You 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: Bug in set?

2009-03-12 Thread Kyle Schaffrick

On Wed, 11 Mar 2009 21:51:51 -0700 (PDT)
Raffael Cavallaro  wrote:
> On Mar 11, 11:43 pm, "Stephen C. Gilardi"  wrote:
> 
> > Here are the expressions and results in a simplified notation:
> >
> > #{a b c} - #{a b} => #{c}
> >
> > #{a b} - #{a b c} => #{}
> 
> ok, so I was misunderstanding how difference works. I thought both
> would evaluate to #{c}.
> 
> thanks

clojure.set/difference implements the "relative complement" operation. I
don't see a "symmetric difference" operation in clojure.set, but it
might be useful:

  (defn symmetric-diff
[xset yset]
(difference (union xset yset)
(intersection xset yset)))

It can also be implemented as the union of both relative complements:

  (defn symmetric-diff
[xset yset]
(union (difference xset yset)
   (difference yset xset)))

If you'd like to add it to the set library, I hereby release both
versions into the public domain.

Also, union/difference/intersection/symmetric-diff are binary. Would
there be any interest in a patch to make them n-ary?

-Kyle

--~--~-~--~~~---~--~~
You 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: Git : I'm lazy

2009-02-14 Thread Kyle Schaffrick

On Sat, 14 Feb 2009 22:58:33 -0500
"Stephen C. Gilardi"  wrote:

> 
> On Feb 14, 2009, at 10:44 PM, Kyle Schaffrick wrote:
> 
> > Hmm, forgive a possibly stupid question: Do you not also need to do
> > a "git update" to update your working copy to the new head revision?
> >
> > I don't know git that well, but it seems like many DVCSs like  
> > mercurial
> > distinguish between "pull" and "update".
> 
> I haven't worked with mercurial.
> 
> In git, "pull" is a command that combines "fetch" and "merge". There  
> is no "git update".
> 
> http://git.or.cz/gitwiki/GitDocumentation
> 
> --Steve
> 

Doh! Sorry, I mix them up easily. I tend to reach for hg for my own
code, but am getting acquainted with git for others' projects. They just
have to overload words differently, don't they!

Confusingly:

  git fetch = hg pull   
  git pull  = hg pull -u
  git merge = hg update (in "fast-forward" case); hg merge (otherwise)

R'ing-T-F-M next time,
-Kyle

--~--~-~--~~~---~--~~
You 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: Git : I'm lazy

2009-02-14 Thread Kyle Schaffrick

On Wed, 11 Feb 2009 23:07:31 -0500
"Stephen C. Gilardi"  wrote:

> 
> On Feb 11, 2009, at 10:57 PM, Jeffrey Straszheim wrote:
> 
> > I know I should look this up on the web, but I'm really busy these  
> > days.  I do intend to learn git someday, but I'm doing fine with  
> > Subversion for my own work.  However, a lot of you are
> > distributing your libs in git.
> >
> > So, can you give me a quick pointer on how to do two things:
> >
> > 1. Check out someone's project into a folder (read only).
> 
> cd 
> git clone 
> 
> > 2. Update that project when the author makes changes.
> 
> cd 
> git pull
> 
> --Steve
> 

Hmm, forgive a possibly stupid question: Do you not also need to do a
"git update" to update your working copy to the new head revision? 

I don't know git that well, but it seems like many DVCSs like mercurial
distinguish between "pull" and "update".

-Kyle

--~--~-~--~~~---~--~~
You 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: why two list comprehensions are different?

2009-01-03 Thread Kyle Schaffrick

On Sun, 28 Dec 2008 21:48:25 -0600
"David Nolen"  wrote:

> >
> > Yes, but I think maybe there is a bug in Clojure that causes the
> > first case to "work" when it should give a syntax error.  If it is
> > not a bug I do not understand why it ignores the expression.
> >
> 
> It's not a "bug" in Clojure because Clojure doesn't really have
> syntax in the way that you seem to be referring to, and I assume that
> you mean this in the sense that Python has list comprehensions as a
> syntactical feature of the language.  A list comprehension in Clojure
> is just a macro not any part of the "core" language so to speak.
> Much of Clojure is like this.
> 
> The macro could do some sort of syntactical checking.  But in this
> case it doesn't really seem like it's worth it.  You could of course
> re-implement your own version of list comprehension that does
> incorporate this.  Unlike Python where this is probably not realistic
> (you can't easily implement new Python syntax for yourself), Clojure
> being a Lisp makes this quite easy.
> 

I don't think the "Lisps have no syntax" card should be played to excuse
silent failures of the sort that create mysterious and difficult to
find/understand bugs. The "you can roll your own version" thing doesn't
really hold up for me, not even in a Lisp: people who reimplement custom
versions of basic language/library features in their app code are a
regular staple on The Daily WTF, for good reason :)

If this had happened to me I know *I* would be disappointed that it
wasn't caught automatically, since A) I would guess without immediate
proof that it isn't terribly difficult to do so, and B) this kind of
behavior tends to cause me hours of frustrating debugging. If it is
otherwise customary and expected that Clojure code throws exceptions
when called incorrectly, my intuition would be that silently generating
[incorrect] output for a malformed argument list is broken behavior.

"It is not blowing up," I would reason, "and thus it must be a logical
error in the structure of my algorithm, not something piddly like
accidentally omitting a keyword."

If you don't want to throw a syntax error (since you're right in the
sense that it *isn't* a syntax error) it should at least throw
something, for example Python tends to use a TypeError for malformed
argument lists.

Of course if someone can explain how this behavior gives list comps
useful properties and (perhaps more importantly) could have been
expected, then I'll happily retract this!

> David

-Kyle

--~--~-~--~~~---~--~~
You 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: Persistent storage

2008-12-18 Thread Kyle Schaffrick

On Thu, 18 Dec 2008 18:06:40 -0500
Chouser  wrote:

> 
> On Thu, Dec 18, 2008 at 4:47 PM, r  wrote:
> >
> > Is is possible to use some kind of backend storage for Clojure's
> > data structures? I mean something like Perl's "tie" function that
> > makes data structures persistent (in sense of storage, not
> > immutability).
> >
> > Such storage should be inherently immutable the way Clojure's data
> > are (so a simple wrapper on sql is probably not good enough) and
> > provide means of querying database and indexing (ideally
> > multidimensional).
> 
> I would looove this.
> 

This occurred to me the other day as well; the name "Mnejia" which
popped into my head says a lot about the sort of thing I had in mind :)

> > I wonder if this could be at library level or would rather have to
> > be hard-coded into Clojure itself. Did anyone try to do it?
> 
> I've pondered a couple approaches, though only enough to find
> problems.
> 
> One approach would work act like a Clojure collection, with structural
> sharing on-disk.  This would be great because it would have
> multi-versioning and transaction features built right in.  It would
> also have the potential to cache some data in memory while managing
> reads and writes to disk.
> 

This is an interesting observation.

Something in the vein of OTP's Mnesia for Clojure would be *very* cool
indeed, and I have been thinking a lot about ways to implement
distribution mechanisms for Clojure on top of which such a thing could
be built. I imagine however that even sans distribution it would be
quite powerful and useful, and a fun project.

[ Mostly off-topic musings follow :) ]

The big problem with mimicking Mnesia for distribution is that a lot of
Erlang distribution idioms (used heavily in Mnesia AFAIK) rely on BEAM's
ability to marshall funs across the network (and indeed I think Mnesia
can even use that to serialize them on disk tables). If serialization of
a fun is possible in Clojure, doing it is way over my head :) Obviously
if you can serialize the sexp before the compiler gets ahold of it, this
is easy, but usually you don't get that lucky.

If one were able to marshall a Clojure fun, I had envisioned
constructing a sort of "distributed send", probably built atop one of
the many good message-queueing protocols already extant, that can be
used to cause that fun to be run on a remote Agent, giving you a more
Clojure-flavored distribution mechanism. Not RPC, but not exactly Actor
model either.

H... :)

-Kyle

--~--~-~--~~~---~--~~
You 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: replace (rand)

2008-12-04 Thread Kyle Schaffrick

On Thu, 4 Dec 2008 00:07:56 -0800 (PST)
"don.aman" <[EMAIL PROTECTED]> wrote:
> 
> Since we're being all high-level, it'd be good for a random function
> which allows us to specify the range of numbers, since % doesn't
> promise an even spread of probabilities (especially for large ranges).

If one plans to get very involved in the business of noise, I would
recommend exploring Boost's random library for C++. It provides an
array of entropy sources (MT, lagged fib, nondeterministic sources,
etc) and statistical distributions (uniform, normal, lognormal, and a
BUNCH more), and the user composes one of each to produce a generator.

I don't know how well the API would translate into a functional
programming style, but such a separation turns out to be fairly elegant.
Of course, it's probably also far too specialized to belong in the core!

As much flak as C++ gets, I feel like Boost goes a *long* way towards
making C++ productive and enjoyable for certain kinds of problems. There
are a lot of smart folks behind Boost and I personally wouldn't hesitate
to steal good ideas from them :)

-Kyle

--~--~-~--~~~---~--~~
You 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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: SVN or release?

2008-11-29 Thread Kyle Schaffrick

On Sat, 29 Nov 2008 19:05:23 -0800 (PST)
Parth Malwankar <[EMAIL PROTECTED]> wrote:
> 
> Regarding Chimp, maybe you can try Gorilla:
> http://groups.google.com/group/clojure/browse_thread/thread/c8b7bc3106c39791
> I haven't used it personally yet.
> 

My mistake, I actually did mean Gorilla and not Chimp.

In any case, thanks for everyone's input. Since there's a 1.0 on the
horizon I'll standby for that and continue my tinkering with this
release. :)

-Kyle

--~--~-~--~~~---~--~~
You 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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



SVN or release?

2008-11-29 Thread Kyle Schaffrick

Hi all,

I've been playing with Clojure for a few days now, following the mailing
list, searching and tinkering, etc. I'm really excited about this
language!

I'm running the latest packaged release, and I'd like to start writing
some more serious "spikes" in Clojure, but I'm starting to get the
impression that I should be using the SVN version instead to get the
latest hotness.

I say this because I've noticed a few things here and there in 3rd party
code and in the docs that are not working, it seems, because they depend
on features/changes only present in SVN, such as the Java method call
operators, and some namespace shuffling. Being a Vimmer, for example, I
tried to set up Chimp and am getting a mysterious exception from the
STM's innards when Vim tries to connect to Chimp's REPL listener.

Is there a general recommendation here? Should I be on SVN or is this
just my bad luck :)

Thanks,
-Kyle

--~--~-~--~~~---~--~~
You 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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---