ANN: inet.data 0.5.1

2012-10-25 Thread Marshall T. Vandegrift
Hi:

Inet.data is a Clojure library for modeling various Internet-related
conceptual entities as data.  It is intended to support applications
which are *about* the modeled entities versus *interfacing* with them.

It presently contains types and associated APIs for representing IP
addresses, IP networks, and DNS domains.  None of the provided functions
will ever perform any sort of DNS resolution or other network operation
on the entity represented.  Instead, it supports such operations as
network address enumeration, network and DNS zone set membership tests,
and domain suffix list lookups.

Overview documentation and source code available at:

https://github.com/llasram/inet.data

Detailed API documentation at:

http://llasram.github.com/inet.data/

Leiningen dependency coordinates:

[inet.data 0.5.1]

Feedback and contributions welcome!

-Marshall

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

2012-08-15 Thread Marshall T. Vandegrift
David Nolen dnolen.li...@gmail.com writes:

 Should core.logic support specific versions of Lein? Ideally Lein 2
 would support Lein 1.X files.

My understanding is that the reason the new version is lein 2.0 instead
of 1.8 is because it does break backwards compatibility.

However, if this is the only problem, it's fairly easy to support both
versions -- just include both :source-path and :source-paths entries in
the project map.

-Marshall

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


Re: Using gen-class to generate methods with same names and arities but different type signatures

2012-08-03 Thread Marshall T. Vandegrift
David Greenberg dsg123456...@gmail.com writes:

 I can easily generate a map from signatures to implementations, but I
 need to generate the class with all the overloads.

 Is there any way to do this? Should I resign myself to writing out a
 .java file, and compiling that?

In my experience just writing a stub Java class for this sort of
situation is the simplest solution.  I've found that `gen-class` works
well for interop when needing to extend an abstract base class or
similar scenarios.  But when the need is less to interop with the JVM
than specifically with Java, it is far easier to wire from Java into
Clojure than vice versa.

-Marshall

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: binding vs futures bug or feature (or more likely, am I missing the picture?)

2012-08-03 Thread Marshall T. Vandegrift
Daniel Silén nimbus...@gmail.com writes:

 If I rebind a var's value it receives the new value - but it shouldn't, 
 because it is in another thread, right?!

Clojure 1.3 introduced a feature known as binding conveyance, which
causes the functions passed in for futures and agent actions to be
wrapped so as to capture the active thread local binding frame at
instantiation.  You can achieve a similar effect yourself (although the
mechanism differs) by using the `bound-fn` macro or wrapping an existing
function with `bound-fn*`.

I believe the idea was to make the behavior of dynamic vars in these
contexts less surprising / more useful, but YMMV.

-Marshall

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


Re: What concurrency models to document?

2012-08-02 Thread Marshall T. Vandegrift
Brian Marick mar...@exampler.com writes:

 Which raises the question: *is* concurrency actually a strong selling
 point for functional languages?

It definitely was/is for me.  I'd avoided threads for most of my
career-to-date because in imperative languages any thread could mutate
any value to be anything at any point.  This is difficult to reason
about when the code is written correctly, and then in C you have the
added fun that an error could lead to that malevolent thread writing to
absolutely any address in memory.  Complete undebuggable madness!

So I'd generally reached for processes in order to achieve concurrency.
Using processes doesn't get rid of deadlocks etc, and introduces
additional copying overhead if e.g. communicating over pipes, but does
shrink the problem one needs to think about down to just the set of
mechanisms explicitly used to communicate between the processes.

IMHO, FP in general and Clojure in particular does two big things
regarding concurrency:

  (1) By using immutable values, provides the same conceptual
  shrinking as using processes does in imperative languages, only
  without (well, with reduced) copying overhead.  The concurrency
  problem is limited to just the interactions over the relatively
  small number of explicit concurrency points.

  (2) The ability to build higher-order concurrency abstractions which
  completely encapsulate recurring patterns.  When using pure
  functions on immutable data, e.g. `pmap` and `reducers/fold`
  really do give you auto-concurrency for certain patterns of
  concurrent operations.

Just my 2 cents,

-Marshall

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

2012-07-31 Thread Marshall T. Vandegrift
Vinay D.E devi...@gmail.com writes:

 I am a newbie and was doing some exercises when I ran across something that 
 I don't understand.
 I am trying to count the number of elements in an array less than 100.

 My first attempt didn't work. The counter returns 0

 (let [a (atom 0)
   i (take-while (fn[x] (swap! a inc) ( x 100))  [1 2 3 4 5])]
   [@a i])  = [0 (1 2 3 4 5)]

The primary concrete problem is laziness, but fundamentally this sort of
mutable-imperative algorithm doesn't play nice with Clojure's core
features.

The sequence returned by `take-while` is lazy, and none of the function
applications required to generate that sequence actually happen until
something forces evaluation of the sequence elements.  So when you get
the result of `[@a i]` what happens is:

  (1) `@a` is evaluated; nothing else has actually happened yet, so the
  result is still the initial value of `0`.

  (2) `i` is evaluated; now the sequence is forced and generated, and as
  a side-effect the atom is updated.

Instead of depending on mutating side-effects to do these sorts of
calculations, most of the Clojure standard library assumes that you'll
be working with (largely) pure functions which operate primarily in
terms of their parameters and return values.  As an aside, you probably
wanted `filter` instead of `take-while` even for what you were trying to
do in the first place -- you should be able to figure out the difference
from the docs.  So, using pure functions, we can something as simple as:

  (count (filter #( x 100) input-sequence))

HTH,

-Marshall

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

2012-07-18 Thread Marshall T. Vandegrift
Warren Lynn wrn.l...@gmail.com writes:

 I have a hard time understanding why there is a need to retry when
 doing swap! on an atom. Why does not Clojure just lock the atom
 up-front and do the update?

This is just my two cents, but I think the/one big reason is that
Clojure atoms just *are* non-locking STM-based synchronized references.
They allow you to handle shared, synchronous, independent state, but
that's their typical use-case, not their definition.  The Clojure atom
is defined in terms of mechanism, not application.

If you want locks, the Java standard library has locks aplenty.  My
understanding of the Clojure idiom is that when traditional
threads-locks-and-queues concurrency is the best fit for the job, then
just use it.  My reading of the standard library suggests a strong
preference for using higher-level constructs which leverage shared
thread pools (futures and agents) over raw threads, but absolutely no
shame in using e.g. LinkedBlockingQueue.

Here's my quick stab at something implemented atop Java read-write
locks:

  https://gist.github.com/3135772

-Marshall

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

2012-04-15 Thread Marshall T. Vandegrift
Stuart Sierra the.stuart.sie...@gmail.com writes:

 Clojure doesn't currently support generating Java classes dynamically,
 but you could hack the compiler to allow it.

And if you don't feel like doing it yourself, check out shady and
`shady.gen-class/gen-class`:

https://github.com/llasram/shady/blob/master/src/shady/gen_class.clj#L25

-Marshall

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


[ANN] shady 0.1.0: JVM interop classes with less heartache

2012-04-04 Thread Marshall T. Vandegrift
Hi all:

Shady is intended to be a collection of JVM interop facilities.  Right
now it contains two useful pieces of functionality for producing iterop
classes: a version of `gen-class` supporting dynamic redefinition like
`deftype`; and a `defclass` macro providing a `deftype`-like interface
to that `gen-class`.

For example:

(ns example.defclass
  (:use [shady.defclass :only [defclass]]))

(defclass Example [field1 field2]
  :extend BaseClass
  :constructors {[String String] [String]}

  Example
  (-init [arg1 arg2] [[arg1] [arg1 arg2]])
  (newMethod ^String [^int param]
(str example: field1 : param : field2))

  BaseClass
  (override ^Long [^Class class] 10)

  SomeInterface
  (implementedMethod []
Types defaulting to Object, as you'd hope.))

The interface is cleaner (IMHO), and normalized with the other Clojure
type-definition facilities.  The support for dynamic class redefinition
is clinically proven to produce 73% less heartache for interop
situations where you need full JVM classes.  Be warned though, under the
hood `defclass` does still use the same class-generation code as
`gen-class`, with all that implies (performance, methods backed by
functions bound to vars in the implementing namespace, etc).

You can get the source from github:

https://github.com/llasram/shady

And the jar from Clojars:

[shady 0.1.0]

This is the first Clojure library I'm pushing for broader consumption,
so feedback is more than welcome.

-Marshall

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

2012-04-04 Thread Marshall T. Vandegrift
octopusgrabbus octopusgrab...@gmail.com writes:

 Is there any reason to compile a Clojure library with :aot?

Here's all the reasons I know of for doing AOT-compilation:

  - The code produces JVM classes with `clojure.core/gen-class`, which
only produces any results when compiling.

  - The code needs to expose a JVM class as an entry-point for a JVM
framework which expects to find and instantiate a class through
reflection.  (Usually in tandem with the previous case.)

  - One wishes to build and distribute source-less JARs of only the
compiled code.

Any I'm missing?

An open-source Clojure library intended for use from Clojure might hit
the first case, but I don't believe very frequently.

-Marshall

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

2012-04-03 Thread Marshall T. Vandegrift
Marshall T. Vandegrift llas...@gmail.com writes:

 So, is this entirely expected behavior?  Or am I missing something
 which would make initializing the defining namespace happen as part of
 a static initializer for the AOTed `deftype` class?

To answer my own question, the Clojure wiki page on the 1.2-introduced
datatypes [1] includes loading accompanying namespace for deftype? on
the same ideas list as Explicit ctor sigs? ... with bodies?
Slogging through the compiler codebase shows that `deftype` indeed does
not include the necessary code in generated classes' `clinit`s.

Somewhat-relatedly, does anyone know why `gen-class` doesn't jump
through the same class-loader hoops that `deftype` does in order to
support iterative development within the same REPL session?  By grabbing
the private clojure.core/generate-class function, I was able to cobble
together an alternative version which seems to work.

[1] http://www.assembla.com/wiki/show/clojure/Datatypes

-Marshall

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


Initializers for AOTed deftype classes

2012-04-01 Thread Marshall T. Vandegrift
Hi,

I'm trying to define some bits of Hadoop glue using `deftype` from
Clojure.  I'm using Leiningen to produce an AOT-complied JAR of the
generated classes.  At runtime, Hadoop uses reflection to load classes
specified by name in (non-code) configuration.  Hadoop is able to locate
and instantiate instances of the class without issue, but then:

  java.lang.IllegalStateException: 
Attempting to call unbound fn: #'byteable.api/byteable?

That particular example is for a var in a different namespace, but vars
in the same namespace as that which `deftype`s the class cause the same
problem.  If I modify the type's entry-point methods to first `(require
'deytping.namespace)`, then everything works fine.

So, is this entirely expected behavior?  Or am I missing something which
would make initializing the defining namespace happen as part of a
static initializer for the AOTed `deftype` class?

Thanks!

-Marshall

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

2011-12-31 Thread Marshall T. Vandegrift
Alan Malloy a...@malloys.org writes:

 Stuff like this always worries me. It may happen to work now, but I
 doubt if that's a guarantee. extend-protocol's contract is that you
 give it a Symbol, which it resolves into a Class. It surely isn't
 expecting a Class as an argument, because you can't enter that as a
 source-code literal. If you give it a Class, it could conceivably do
 something dreadful like try to call (resolve s) on it to figure out
 what Class you mean, and that will fail when passed a Class.

I'm not entirely happy with it either, but I don't think the situation
is quite that dire.  The docstring for `extend-protocol' doesn't say
anything about *how* it divides up the stanzas for extended types, and
as pointed out elsewhere in this thread the implementation uses seq vs
not-seq, not symbol? vs not-symbol?.  The docstrings for `extend-type'
and `extend' explicitly say that they take a type/class -- I'd
interpret that to mean that they can be called with anything which
resolves to a type/class via normal resolution methods, including a
literal value generated via #=.

 For that matter, trying out your example, it doesn't seem to work for
 me. The first fix is to use java.lang.Class instead of just Class,
 since reader evaluation happens in a no-frills environment.

Apologies -- I just modified the OP's original example without thinking
it all the way through or running the code.  One does need to specify
java.lang.Class/forName, which is what I've been doing in my own source.

 But after that, it seems the extend-protocol just silently does
 nothing:

(Addressed by another poster.)

-Marshall

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

2011-12-30 Thread Marshall T. Vandegrift
Peter Taoussanis ptaoussa...@gmail.com writes:

 Thanks- that explains it: dropping to extend works as expected.

Another option I've been making use of for exactly this situation is to
use the #= reader macro to evaluate the Class/forName at read-time.
Something like:

  (extend-protocol MyProtocol
java.lang.Integer (action [x] Integer)
#=(Class/forName [B) (action [x] ByteArray))

It may not be ideal stylistically, but lets you use extend-protocol in
such situations.

-Marshall

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

2011-12-07 Thread Marshall T. Vandegrift
Stephen Compall stephen.comp...@gmail.com writes:

 And may be anyway further generalized:

 (defmacro - [ forms]
   `(- ~@(reverse forms)))

 (- (let [x (foo) y (bar)])
  (when y)
  (let [ ])
  (do ))

Another alternative,

(require '[clojure.algo.monads :as m])

(m/domonad m/maybe-m
  [x (foo), y (bar), :let [z (baz)], :when ( z 5)]
  (+ x y z))

-Marshall

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

2011-11-15 Thread Marshall T. Vandegrift
Konrad Hinsen googlegro...@khinsen.fastmail.net writes:

 That may be a minority, but an implementation based on Common Lisp
 could also open the way to an integration with the world of C, via a
 Common Lisp implementation with a decent C interface.

Integrating the JVM with C via JNA [1] is pretty straightforward.  I've
been doing all my JNA glue in Java so far because JNA depends on a few
features which aren't available / convenient use in Clojure [2], but a
decent Clojure wrapper API probably wouldn't be too difficult.

[1] https://github.com/twall/jna

[2] Structures involve definition of concrete types inheriting from
other concrete types; direct method mapping requires tagging
methods as `native' and providing a class-level static initializer.

-Marshall

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

2011-11-09 Thread Marshall T. Vandegrift
Tassilo Horn tass...@member.fsf.org writes:

 I'm facing the same issue.  I have this macro for java interop:

 (defmacro with-traversal-context
   [[g tc]  body]
   `(let [old-tc# (.getTraversalContext ^Graph ~g)]
  (try
(.setTraversalContext ^Graph ~g ^TraversalContext ~tc)
~@body
(finally (.setTraversalContext ^Graph ~g ^TraversalContext old-tc#)

 But the type hints are gone in the macro expansion, thus I have 3
 reflection warnings per macro application, and real, performance
 critical reflection warnings get lost in the shuffle.

What you appear to be having is actually the different, but
conceptually-related problem of the metadata reader macro and unquote
operations interacting in a way which is consistent, but potentially not
optimal.  Fortunately in your sort of situation, you can work around the
problem by replacing the metadata reader macro with explicit metadata
operations.  Something like the following should work:

  (defn assoc-meta [x  kvs]
(with-meta x (apply assoc (meta x) kvs)))

  (defmacro with-traversal-context
[[g tc]  body]
(let [g (assoc-meta g :tag Graph)
  tc (assoc-meta tc :tag TraversalContext)]
  `(let [^TraversalContext old-tc# (.getTraversalContext ~g)]
 (try
   (.setTraversalContext ~g ~tc)
   ~@body
   (finally (.setTraversalContext ~g old-tc#))

-Marshall

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

2011-10-25 Thread Marshall T. Vandegrift
Alan Malloy a...@malloys.org writes:

 It seems to me that it would be nice to have macros automatically
 include, on their result forms, the metadata from their input
 form. Of course, macros may wish to add metadata as well, so the two
 maps should probably be merged. However, there are certainly some
 problems with this approach: for example if a macro wants to return
 something that can't suppport metadata (like an Integer), the compiler
 needs to be careful not to try to include it. So I'm hoping the
 community can comment on whether this feature would be useful, or
 whether there are fundamental problems with it that I haven't
 foreseen. Is there a reason this can't make it into a future version
 of Clojure?

I think this is an excellent idea.  Overall I believe this reduces the
number of situations in which one needs to be actively aware that a
particular expression will be subject to macro-expansion.  The
alternative-world where the 99% of well-behaved macros returning IMetas
manually forward metadata from form seems like a world with way too
much boilerplate to me.

Forwarding metadata does preclude macros which use metadata applied to
form as parameters and construct new metadata which may not include the
literal values specified in the user-supplied metadata.  I'm not sure
this is a good idea anyway, but this sort of case -- and any others
where metadata should not be forwarded/merged -- could easily be
supported by providing a variation of defmacro with the current
behavior.  Or perhaps by configuring the metadata-forwarding behavior
via metadata on the macro var -- something like:

  (defmacro foo {:forward-meta false} ...) ;; or,
  (defmacro ^:replace-meta foo ...)

If a macro expands to something which doesn't implement IMeta, then I
believe the compiler needs to error out if metadata is applied to it,
just as it does applying metadata to non-IMeta literals.  To do
otherwise would be inconsistent, and result in the same silent data-loss
as macros are yielding today.

This proposal doesn't touch forwarding metadata on forms which become
macro arguments, obviously.  There's still room for inconsistency there,
but I think that's clearly in the court of individual macro authors to
implement the correct behavior.

Are there other contexts where metadata should potentially be forwarded?
I don't know how often this comes up, but:

  (=  (meta ^:foo (quote foo)) (meta (quote ^:foo foo)))
  ;; = false

-Marshall

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


Re: Code problem: setting an atom from a deref'd atom that's inside a let.

2011-10-25 Thread Marshall T. Vandegrift
Tim Robinson tim.blacks...@gmail.com writes:

 = (defn oops! []
 (let [x1  (atom (hash-map))
   v1  (filter
 #(let [xv1 (@data %)]
(if (= xv1 v1)
(swap! x1 assoc :k1 other)))
(keys @data))
   rxv (reset! flag @x1)]
   (println v1)))


 So why didn't the first version with deref work?

Because `filter' produces a lazy list, which isn't realized (and the
side effects generated) until your call to `println'.

Furthermore, the documentation for `filter' explicitly notes that pred
must be free of side-effects.  Looking at the implementation, I'm not
sure why function-argument purity matters more for `filter' than any
other sequence-generating higher-order function.  Does anyone else know
the reason?

-Marshall

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


Potential bug: pmap vs chunked seqs

2011-10-21 Thread Marshall T. Vandegrift
Hi:

I found what I think might be considered a bug, but I'm not certain.
The doc-string for `pmap' just says that the passed-in function is
applied in parallel, but the code as-written is pretty clearly
intended to keep only (+ 2 #CPUS) future-wrapped function applications
realized at a time.  It works exactly that way for non-chunked seqs, but
when called with a chunked seq instead keeps realized some arbitrary
number of futures between (+ 2 #CPUS) and the next multiple of 32.

Given that the code for `pmap' hasn't changed since chunked seqs were
added to Clojure, this feels like a bug to me, but the parallelism
semantics for `pmap' aren't exactly strictly defined.

Is this worth opening a ticket for in the Clojure issue tracker?

-Marshall

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

2011-10-21 Thread Marshall T. Vandegrift
Stefan Kamphausen ska2...@googlemail.com writes:

 Chunked seqs are supposed to realize more elements than you
 consume. That's for performance reasons.  But since you will only ever
 apply side-effect-free functions to seqs, that will make no
 difference, no?

Sorry, yes, I'm talking about within the code of `pmap'.  It creates a
lazy seq of futures of application of the passed-in function to the
passed-in collection via (map #(future (f %)) coll).  Realizing elements
of *that* seq has the side-effect of allocating/spawning a thread from
the futures thread-pool.  If `coll' can be turned into a chunked seq,
then the futures will be realized -- and threads allocated or spawned --
in chunks of 32.  If `coll' cannot be turned into chunked seq, then only
(+ 2 #CPUS) threads will be allocated/spawned at a time.

I think clarifying that has convinced me that this is definitely bug,
just because the side-effects are inconsistent.  I don't think that the
chunkability (chunkiness?) of the collection argument should affect the
degree of parallelism.

-Marshall

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

2011-10-18 Thread Marshall T. Vandegrift
Dusan dusan.milorado...@gmail.com writes:

 (symbol(str (str (: %   vv 

This expression is the (immediate) problem child.  You are producing a
symbol which contains literal space and parenthesis characters embedded
in it.  When you print out the macro-expansion, it looks fine, but the
actual forms generated contain that weird symbol instead of the expected
list structure.

You do have other problems though -- 

  - A symbol prefixed with a colon is just a symbol prefixed with a
colon, not a keyword.   You need to use the `keyword' function to
create a keyword from a symbol or string.

  - Instead of calling `gensym' directly, it's probably easier to just
use autogensyms in this sort of situation.

For fun, here's a (hopefully) more idiomatic version:

(defmacro defrecord-withstr [name fields columns include?]
  (let [displayed (- (if include? columns (remove (set columns) fields))
   (map keyword))]
`(defrecord ~name ~fields
   Object
   (toString [this#]
 (str/join   ((juxt ~@displayed) this#))

-Marshall

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

2011-10-17 Thread Marshall T. Vandegrift
Guofeng Zhang guof...@radvision.com writes:

 I do not understand why `'~v has be to used this way. If I used
 `~v instead (that is, remove the quote), it still works. So my
 question is, why ~v needs to be first quoted and then syntax-quoted?

I'm not the most experienced Clojure programmer, but I'll have a go:

The key is to count the levels of quoting, and make sure they match what
you need at each level for each form.  Using just `~ is (almost) a
no-op.  Putting ' in between them yields the a form containing the
quoted *value* of v, which is equivalent to the (possibly clearer)
`(quote ~v).  The quoting comes into play for symbols, because quoting
captures any symbols as literal symbol objects vs whatever they resolve
to in the lexical scope.  If you pass {'a 'one} in for the ctx argument
to contextual-eval as-is, then the symbol `one' ends up quoted in the
generated let, and `a' properly bound to the symbol object.  If you
modify the function to *not* quote the value, then an unquoted `one' get
inserted instead, and the function throws an error because `one' is
unbound.

HTH,

-Marshall

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

2011-10-12 Thread Marshall T. Vandegrift
Stuart Sierra the.stuart.sie...@gmail.com writes:

 I was a little worried about this when the exception behavior for fns was 
 changed. I think it's solvable, but don't know right now what the solution 
 is.

I'm not incredibly experienced with Java, but would using a Java
construct which tricks the language into allowing unchecked exceptions
be too crazy?  I've seen references to both of these approaches, but
haven't actually tried either for anything:

  
http://james-iry.blogspot.com/2010/08/on-removing-java-checked-exceptions-by.html
  http://projectlombok.org/features/SneakyThrows.html

The former even came up on #clojure, I believe.

-Marshall

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

2011-05-04 Thread Marshall T. Vandegrift
André Thieme splendidl...@googlemail.com writes:

 Please try this minimal example in your REPL:
 (defn f [x] (fn [] x)) ; the closure factory
 (def foo (f 0)) ; a useful instance
 (defmacro bar [] `(let [a# ~foo]))
 and then call (bar)

I'm new to Clojure and don't have much experience with Lisps in general,
but trying to do this seems weird to me.  My understanding is that
macros are, well, macros -- code which is expanded at compile-time to
other code.  In which case the interface the macro facility provides
isn't a set of compiler hooks, but just the ability to factor and
abstract the same code you could write without the macro facility.  What
ultimate code-expansion are you trying to achieve?  Perhaps there's a
different way to do it which works within the confines of pure code
re-writing.

-Marshall

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

2011-05-04 Thread Marshall T. Vandegrift
Alessio Stalla alessiosta...@gmail.com writes:

 The key point is that in Lisp code does not mean text [1]. Code is
 made of data structures - lists, symbols, vectors, numbers, ... - and
 macros are just functions that operate on those data structures.

Hmm, interesting.  One of the things that's drawn me to learning Clojure
is the malleability of code as data, but I hadn't thought about it as
potentially running that deep before.  Thanks for phrasing that in a way
that clicked for me.

 In other words, valid code is no longer determined by the reader (i.e.
 the parser), but by the compiler and/or the interpreter, that take a
 rich data structure as input. The reader is only useful to us humans
 to enter code into the system.

OTOH, the compiler still needs a defined interface.  The data structures
the reader is able to produce seem like a convenient definition for what
data structures the compiler should meaningfully consume.  Obviously the
reader producing structures the compiler can't consume is useless, but
the compiler consuming structures the reader can't produce seems equally
problematic to me.  It seems like code which doesn't have a textual
representation would be much more difficult to reason about.  Without
guaranteeing a mapping from every valid compiler input to text which
causes the reader to directly generate that input, it becomes impossible
to inspect what the compiler is actually consuming.

-Marshall

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