Re: Keyword namespaces

2010-09-19 Thread Kyle Schaffrick
On Sun, 19 Sep 2010 12:22:54 -0700 (PDT)
ataggart alex.tagg...@gmail.com 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 k...@raidi.us 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


Re: existing idiom for delaying a future ?

2010-08-05 Thread Kyle Schaffrick
On Thu, 5 Aug 2010 16:05:07 +0200
Laurent PETIT laurent.pe...@gmail.com 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: existing idiom for delaying a future ?

2010-08-05 Thread Kyle Schaffrick
On Fri, 6 Aug 2010 00:04:08 +0200
Laurent PETIT laurent.pe...@gmail.com 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: Symbol substitution in macro

2010-08-04 Thread Kyle Schaffrick
On Wed, 4 Aug 2010 14:58:46 -0400
Andrew Boekhoff boekho...@gmail.com 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 boekho...@gmail.com 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


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 quza...@googlemail.com 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 michal.marc...@gmail.com 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 (#core$constantly__4695$fn__4697
  clojure.core$constantly__4695$fn__4...@7087e9bf))
  user= (list-of-fn (constantly 1))
  #CompilerException java.lang.ExceptionInInitializerError (REPL:14)

-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-16 Thread Kyle Schaffrick
On Thu, 15 Jul 2010 23:08:27 -0700 (PDT)
Quzanti quza...@googlemail.com 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 quza...@googlemail.com 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 karl.kru...@gmail.com wrote:
 
 On Jul 11, 11:55 am, stewart setor...@gmail.com 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: Moving Window Function

2009-06-23 Thread Kyle Schaffrick

On Mon, 22 Jun 2009 23:36:25 -0700 (PDT), Sean Devlin
francoisdev...@gmail.com 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: Moving Window Function

2009-06-23 Thread Kyle Schaffrick

On Tue, 23 Jun 2009 10:20:52 -0400
Kyle Schaffrick k...@raidi.us wrote:
 
 On Mon, 22 Jun 2009 23:36:25 -0700 (PDT), Sean Devlin
 francoisdev...@gmail.com 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 Tue, 23 Jun 2009 18:23:01 +0200
Christophe Grand christo...@cgrand.net 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: 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 laurent.pe...@gmail.com 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: Clojure in Computing in Science and Engineering

2009-06-22 Thread Kyle Schaffrick

On Sun, 21 Jun 2009 14:39:37 +0100, Jon Harrop j...@ffconsultancy.com
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 j...@ffconsultancy.com 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 d2387...@bsnow.net wrote:
 On Jun 17, 3:20 am, kkw kevin.k@gmail.com 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 robert.l...@gmail.com 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 laurent.pe...@gmail.com wrote:

 
 Hi David,
 
 2009/4/20 David Nolen dnolen.li...@gmail.com:
  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: 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 danieljom...@gmail.com 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
-~--~~~~--~~--~--~---



Re: proposed new contrib: java-utils

2009-04-03 Thread Kyle Schaffrick

On Fri, 3 Apr 2009 10:17:33 -0400
Stuart Halloway stuart.hallo...@gmail.com 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
-~--~~~~--~~--~--~---



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 mark.engelb...@gmail.com wrote:
 
 On Mon, Mar 23, 2009 at 7:31 PM, Vincent Foley vfo...@gmail.com
 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 Wed, 11 Mar 2009 21:51:51 -0700 (PDT)
Raffael Cavallaro raffaelcavall...@gmail.com wrote:
 On Mar 11, 11:43 pm, Stephen C. Gilardi squee...@mac.com 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: Bug in set?

2009-03-12 Thread Kyle Schaffrick

On Thu, 12 Mar 2009 12:45:00 -0700 (PDT)
Jason Wolfe jawo...@berkeley.edu 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: 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 m...@kotka.de 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: VimClojure 2

2009-03-12 Thread Kyle Schaffrick

On Thu, 12 Mar 2009 13:30:51 -0700 (PDT)
Mark Volkmann r.mark.volkm...@gmail.com wrote:

 
 On Mar 12, 3:21 pm, Mark Volkmann r.mark.volkm...@gmail.com 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 /var/folders/fd/fduD2R4HFwWXFCpC4prCMk+++TI/-Tmp-/
 v920635/0
 Error detected while processing /Users/Mark/.vim/ftplugin/clojure.vim:
 line  131:
 E171: Missing :endif
 Error detected while processing function SNR9_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: Bug in set?

2009-03-12 Thread Kyle Schaffrick

On Thu, 12 Mar 2009 15:50:16 -0700
Jason Wolfe jawo...@berkeley.edu wrote:
 
 On Mar 12, 2009, at 3:34 PM, Kyle Schaffrick wrote:
 
 
  On Thu, 12 Mar 2009 12:45:00 -0700 (PDT)
  Jason Wolfe jawo...@berkeley.edu 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: Git : I'm lazy

2009-02-14 Thread Kyle Schaffrick

On Wed, 11 Feb 2009 23:07:31 -0500
Stephen C. Gilardi squee...@mac.com 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 the directory within which you want the new checkout
 git clone the git URL you have
 
  2. Update that project when the author makes changes.
 
 cd the git directory you checked out
 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: Persistent storage

2008-12-18 Thread Kyle Schaffrick

On Thu, 18 Dec 2008 18:06:40 -0500
Chouser chou...@gmail.com wrote:

 
 On Thu, Dec 18, 2008 at 4:47 PM, r nbs.pub...@gmail.com 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
-~--~~~~--~~--~--~---



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



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