Re: Enhanced Primitive Support

2010-06-19 Thread Mark Engelberg
I'm confused.  In the latest scheme, what is the eventual plan for
handling a recur to a loop element that was initialized with a
primitive?  Are boxed numbers automatically coerced to the primitive?
Would a long be coerced to a double, or double to long?  Under what
scenarios will you get a warning, and when will you get an error?

I think what troubles me the most about this loop/recur issue is that
the semantics of recur depend completely on whether a variable is
assigned a primitive or boxed numeric type.  To know what the recur
will do, you must know the type of the assigned value.  This has
always been the case, but in the current version of Clojure, provided
you aren't using Java interop, it's relatively straightforward to
know.  Unless the variable or literal is explicitly cast to a
primitive, it's not a primitive.  But now, with the advent of static
functions which can return primitives, it becomes more likely to not
easily be able to determine this fact.  If I say (loop [x (foo 2)]...)
 I have no way of knowing what's going to happen when I recur.  Yes, I
realize that you can run the function and use warnings/errors to find
out.  But I find it unsettling to have a commonly used code form with
semantics I can't predict just by looking at it.

It's attractive that the current proposal gives speed benefits to
common cases with no additional annotation.  But I personally place a
higher value on being able to understand the semantics of my code when
reading through it.  I would prefer a version where loop requires some
sort of explicit annotation on a variable if you want it to require a
primitive upon recur.  (Ideally, I'd probably want the annotation on
the variable using a syntax that mirrors static functions, rather than
the old technique of typecasting the initializer, since the whole
typecasting system makes less sense now that literals and certain
return values are already primitives.  Unifying the syntax and
semantics of using primitives in loops with the syntax and semantics
of using primitives as inputs to static functions makes a lot of sense
to me.)

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that 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 script in the classpath

2010-06-19 Thread rzeze...@gmail.com
On Jun 18, 6:15 pm, Paul Moore p.f.mo...@gmail.com wrote:
 I've just seen a couple of postings which, if I'm not mistaken, imply
 that it's possible to have a Clojure script in my classspath. Is that
 right?

Yes, you can have .clj files on your classpath.  In fact, you can
pretty much have anything on your classpath.  Checkout
java.lang.ClassLoader 
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ClassLoader.html#getResource(java.lang.String)
.  This is what Clojure uses under the covers.

 Can anyone give me a complete example of how this works? (I probably
 need to get the file names and namespaces right, something I'm still
 struggling with - again the Java/JVM requirements for filenames that
 match classnames is a new concept for me).

Let's say I put my clojure.jar on the classpath, but only put the
clojure-contrib source files on the classpath and I want to use the
clojure.contrib.string/blank? function.  Here is a session at the
REPL.  Note that I used a custom script to start the REPL, it prints
out the Java executable and CLASSPATH env variable at the top.

rzeze...@chinaski.local [~] clojure
 JAVA: 
 /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/bin/java
 CLASSPATH: 
 /Users/rzezeski/projects/clojure/clojure.jar:/Users/rzezeski/projects/clojure-contrib/src/main/clojure
Clojure 1.2.0-master-SNAPSHOT
user= (clojure.contrib.string/blank? )
java.lang.ClassNotFoundException: clojure.contrib.string
(NO_SOURCE_FILE:0)
user= (load /clojure/contrib/string)
nil
user= (clojure.contrib.string/blank? )
true
user=

Notice the load function converted my string into a path to the .clj I
wanted.  The initial forward-slash means I want to lookup relative to
the classpath.  The lib I want has the namespace
clojure.contrib.string.  In this case simply convert the periods to
forward-slashes.  You don't specify the .clj extension because Clojure
will first try to load the lib via class file or source depending on
which is newer.  For example, if I tried to load the lib foo.bar.

user= (load /foo/bar)
java.io.FileNotFoundException: Could not locate foo/bar__init.class or
foo/bar.clj on classpath:  (NO_SOURCE_FILE:0)

Now that I've shown you the load function I'm going to pull the rug
from underneath you and tell you not to use it to load your Clojure
libraries.  The idiomatic way to load a lib is via the require
function, which uses load under the covers.  Require allows you to
specify your lib in it's native Clojure tongue.

user= (require '[clojure.contrib.repl-utils :as ru])
nil
user= (ru/show ClassLoader)
===  public abstract java.lang.ClassLoader  ===
[ 0] static getSystemClassLoader : ClassLoader ()
[ 1] static getSystemResource : URL (String)
...

HTH,
-Ryan

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that 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: classpath and require

2010-06-19 Thread rzeze...@gmail.com


On Jun 18, 5:00 pm, Mohammad Khan beepl...@gmail.com wrote:
 C:\Projects.cljjava -cp
 c:\clojure-contrib\clojure-contrib.jar;c:\clojure\clojure.jar clojure.main
 Clojure 1.1.0-alpha-SNAPSHOT
 user= (require 'examples.introduction)
 java.io.FileNotFoundException: Could not locate
 examples/introduction__init.class or examples/introduction.clj on
 classpath:  (NO_SOURCE_FILE:0)
 user=

 C:\Projects.cljecho %CLASSPATH%
 C:\Projects.clj;C:\clojure;C:\clojure-contrib
 C:\Projects.cljdir examples\introduction.clj
  Volume in drive C is xxx
  Volume Serial Number is -
  Directory of C:\Projects.clj\examples

 06/18/2010  04:52 PM                40 introduction.clj
                1 File(s)             40 bytes
                0 Dir(s)  xx,xxx,xxx bytes free

 C:\Projects.clj

You're overriding your %CLASSPATH% variable with your -cp argument
[1].

Try starting your REPL with the following.

java -cp c:\clojure-contrib\clojure-contrib.jar;c:\clojure
\clojure.jar;C:\Projects.clj clojure.main

1: http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/java.html#options

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


Re: Enhanced Primitive Support

2010-06-19 Thread Konrad Hinsen
On 18.06.2010, at 15:20, Rich Hickey wrote:

 Which then begs the questions:
 
 - how will someone 'protect' themselves from libraries written using fastmath?

Using fastmath or not would be part of the library specification. Or, in 
general, of the documentation for each individual function. It may not matter 
at all for the user of some functions, but be very important for others.

 - similar looking code will change semantics when the ns switch is made - 
 seems dangerous as it might violate the presumptions of the original authors.

That is true, but it is true for any strategy to introduce new maths semantics 
into Clojure. As soon as there are two, there is a risk for confusion. And even 
if there is only one but different from the one in the past, there is a risk 
for confusion as well.

Konrad.

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


Re: Clojure / Common Lisp Question

2010-06-19 Thread Tim Daly

Clojure is an amazing piece of work.

I'm interested in Clojure for the concurrency.

I'm also interested in the immutable data structure work.
Someone needs to write a paper about the performance
characteristics of immutable structures when the whole
structure changes. That is, what are the performance
comparisons of mutable/immutable for various sorts?

I'm using Clojure as a console front end to our
huge Java project. Rather than writing Java programs to
generate test or output I write Clojure.

Rich Hickey's insightful videos have caused me to stop
writing loops whenever possible. For me this is the same
level of thinking-change that happened when I moved to
using Structured Programming rather than GOTO (in Fortran).
Rich needs to write a paper called
  Loops considered harmful

Common lisp, however, gives me precise machine-level to
massive function semantics, e.g. (car ...) is a machine
pointer and (integrate ...) is a huge function but I can
freely mix them in (integrate (car ...)). I don't feel the
same one-ness in Clojure/Java.

In general, I'm a common lisp bigot :-)

Tim Daly

rob levy wrote:
As an informal survey of people who use both Clojure and Common Lisp 
for different projects, what do you see as the main determining 
factors behind your choice to use either Clojure or Common Lisp for a 
project,  given the present state of Clojure.  Let's only assume we 
are talking about projects you completely own and have complete 
freedom to do what you want with.


Common lisp:
   Compiled on the processor, fast.
   Reader macros. 
   Quality, not quantity of libraries.
   Multi-paradigm programming with no nudging -- programmer has 
freedom to be insane/bizarre in ways Clojure makes hard (see Let Over 
Lambda for examples)

   Downsides:
 Hard to deploy. -- but not a problem as server side of web app
 Can't run on on GAE. -- need to run a server or rent/maintain 
virtual server.

 Limited to native librares, though they tend to be awesome.

Clojure:
   Neat concurrency stuff.
   Better deployment. 
   Can run on Google App Engine. (maybe ABCL can too, but I wouldn't 
want to use that personally).

   Lots of Java libraries, many more than for CL.
   Increasing a large number of awesome native libraries.
   Downsides:
  As server side of web app in apache, less straigtforward 
requires Tomcat, Java crud.
  Java interop is great-- but Java itself sucks!  There is an 
impedance mismatch of language semantics.
  The nudging of paradigm/idiom makes many things easier in Common 
Lisp.
  Lots of cool benefits of Clojure (such as any/all GUI stuff for 
example) depend on crufty Java nonsense you must contend with.



So, for me at this point, if I don't need interesting concurrent 
stuff, and I do my own hosting, Common Lisp in Hunchentoot or mod lisp 
still seems like a superior web development approach.  On the other 
hand if I am doing desktop apps, applets, want to use GAE, etc, 
Clojure seems better.   I feel like as time goes on we will be more 
abstracted away from the pain of Java.


Any thoughts on how you make your decision for specific projects?

Thanks,
Rob
--
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient 
with your first post.

To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en 


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


Re: Enhanced Primitive Support

2010-06-19 Thread Konrad Hinsen
On 18.06.2010, at 15:31, Nicolas Oury wrote:

 In this situation, I would rather have some kind of toggle 
 *use-bigints-by-default* (defaulted to false) used by the compiler.
 Then, if someone needs big integers, he can switch the toggle and recompile 
 everything.
 You wouldn't have to change the libraries ns. 

I don't think it's a good idea to have a compiler switch change the semantics 
of number handling.

 As for being predictable, if you have numbers that can be bigger than 10^19, 
 you would probably know it in advance.
 (indices, counters and the like don't grow that big)

True, but that's on a variable-by-variable basis.

Konrad.

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


Re: Enhanced Primitive Support

2010-06-19 Thread Nicolas Oury
On Sat, Jun 19, 2010 at 3:12 AM, Rich Hickey richhic...@gmail.com wrote:


 I have to say I'm in the 'pay for what you use' camp - you need a box, you
 ask for one. If I don't (and neither do any of those loops), why should I
 have to do extra work to avoid it?

 Rich


 +1.

It is often very easy to spot integers that can grow above 10^18. Again, 
95% of number variables that someone will write in his life never will
attain that because they are somehow referring to a ressource, either in the
computer (counter, indices) or in the real world.

So, except for scientific programming, fact, fib and ackerman, that's not a
problem. (For scientific programming, I argue people should know what to do
with numbers). I still would like to have a real world example were it is
hard to predict and to solve.

On the other hand, having boxed by default is a very significant slowdown
(10% on the strange program I tried, that had already a lot of annotations,
probably 20% or more on most programs), that can never be addressed : you
can't write annotations on every single line of your program.

So, we take a 10/30% speed hit, that won't be solved, mainly because we want
people writing their first Fib or fact function not to have an exception
thrown. I think people can handle this level of complexity.


If boxed is the default, I advocate at least a flag allowing to change that
(and possibly allowing int as a default for embedded stuff).
Most problem with semantic changing flag disappear if the flags have an
order.
It is close to choosing the size of your heap on the command -line, which is
a semantic-changing run-time flag...

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that 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: Basic toolset for non-Java programmer

2010-06-19 Thread Alex Ott
Hello

Paul Moore  at Sat, 19 Jun 2010 00:08:54 +0100 wrote:
 PM - Build tools: There seem to be things like ant, maven, leiningen. How
 PM do they relate to each other? Is there an obvious best answer or
 PM should I be expecting to check them all out depending on my needs? In
 PM that case, are there any good comparisons around?

I use mvn or lein to build clojure code

 PM - Profilers: Same sort of question - do IDEs offer this, are there
 PM standalone tools?

I use VisualVM to profile code

 PM - Testing: I've not really got to the documentation on Clojure's own
 PM testing tools, so maybe that's all I need, but are there testing
 PM frameworks I should look at, that sort of thing?

clojure.test provides enough features to test code

 PM - Deployment: For simple standalone utilities, am I looking at bat
 PM file wrappers (I'm on Windows mainly) to set classpath and the like?
 PM Given that there are some annoying limitations with bat files (nasty
 PM nesting behaviour, ugly console windows for GUI applications), are
 PM there any commonly used better solutions? For web applications, I
 PM gather that a servlet container (all that fancy J2EE stuff :-)) and
 PM something like compojure is a good place to start. For non-web
 PM long-running services, is it still reasonable to use an application
 PM server, or should I be looking at something to wrap a Clojure app up
 PM as a Windows service (something like Java Service Wrapper
 PM (http://wrapper.tanukisoftware.org/doc/english/download.jsp) came up
 PM for me on a Google search)?

I use procrun from apache commons daemon project to run clojure app on
windows as service. All works fine, except case when you need to load
resources manually.  See ticket #379 in Clojure's Assembly for more details

To build installers I use izpack from maven

-- 
With best wishes, Alex Ott, MBA
http://alexott.blogspot.com/http://alexott.net/
http://alexott-ru.blogspot.com/
Skype: alex.ott

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that 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 the instructions of a simple vm into a function

2010-06-19 Thread Nicolas Oury
There is two way to make a domain-specific language with a clojure back-end
:
- if you want the language to be an extension of Clojure, still to be used
in a REPL or by clojure source
   - you write macros. That's what I call embedded.  There is a lot of
litterature on Embedded Domain Specific Language in functional languages. (A
*lot* in Haskell, for example)
In this situation, eval is most of the time evil.

- you want to read instructions that are very far from Clojure in a file and
execute them. (Your case, not by choice but because of the ICFP  specs).
Then, eval is necessary. But you have to call it only once per compiled
function, ideally, and never while executing the code (for performance).
In your situation, I would write
(defn compile-instruction [instructions] ...)

Then, when reading the instructions
(let [compiled-function (eval (compile-instruction (read-file...)))]
 ...

Then, eval is called once, just after reading and compiling. And
compiled-function is a real Clojure function.

Have fun,

Nicolas.







On Sat, Jun 19, 2010 at 3:39 AM, Eugen Dück eu...@dueck.org wrote:

 Thanks Nicolas,

 your first variant resembles the generated code much closer than my
 initial approach, which is great. I need the eval though, to be able
 to pass in non literals. In my real program I'm reading the
 instructions from a binary file. So if I want to be able to do
 something like this:

 (def three-instructions '([+ 2 3] [- 0 1] [+ 1 0]))
 (def compiled (compile-instructions three-instructions))

 The macro would have to look like this:

 (defmacro compile-instructions
  [instructions]
  (let [memory (gensym memory-)]
   `(fn [~memory]
  ~@(map (fn [[op m1 m2]]
 `(aset ~memory ~m1 (~op (aget ~memory ~m1) (aget
 ~memory ~m2
(eval instructions)

 But I like your suggestion to turn it into a function even better:

 (defn compile-instructions
  [instructions]
  (let [memory (gensym memory-)]
(eval
 `(fn [~memory]
   ~@(map (fn [[op m1 m2]]
`(aset ~memory ~m1 (~op (aget ~memory ~m1) (aget ~memory
 ~m2
   instructions)

 And

 (def compiled (compile-instructions three-instructions)))

 just works as before. So I guess macros don't add any value here.

  eval is evil, but eval is not evil is a compiler (you have to evaluate
 the
  code you read).
  However eval is evil again in an embedded compiler, when you use macro
 to
  extend Clojure.

 What do you mean by embedded compiler?

 Eugen

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


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

Re: classpath and require

2010-06-19 Thread Rasmus Svensson
2010/6/18 Mohammad Khan beepl...@gmail.com

 C:\Projects.cljjava -cp
 c:\clojure-contrib\clojure-contrib.jar;c:\clojure\clojure.jar clojure.main
 Clojure 1.1.0-alpha-SNAPSHOT
 user= (require 'examples.introduction)
 java.io.FileNotFoundException: Could not locate
 examples/introduction__init.class or examples/introduction.clj on
 classpath:  (NO_SOURCE_FILE:0)
 user=

 C:\Projects.cljecho %CLASSPATH%
 C:\Projects.clj;C:\clojure;C:\clojure-contrib
 C:\Projects.cljdir examples\introduction.clj
  Volume in drive C is xxx
  Volume Serial Number is -
  Directory of C:\Projects.clj\examples

 06/18/2010  04:52 PM40 introduction.clj
1 File(s) 40 bytes
0 Dir(s)  xx,xxx,xxx bytes free

 C:\Projects.clj


Hello!

To me it looks like you have gotten the most things right. As I see you
understand, you must have clojure, clojure-contrib and the source on the
class path. However, how these are specified can be a bit tricky. There are
basically two cases: directories and jar files.

When using jar files, the jar file itself must be in the class path, not the
directory which contains it. In our case, the entries would be
c:\clojure\clojure.jar and c:\clojure-contrib\clojure-contrib.jar, just as
you wrote.

When using folders with clojure source files or ahead-of-time compiled
classes, the directory that contains the folder that represents the topmost
component of the namespace. For example, in your case the namespace
examples.introduction is stored in the file
C:\Projects.clj\examples\introduction.clj so the directory C:\Projects.clj\
should be inlcuded in the class path.

When Clojure loads the namespace examples.introduction, it will try to find
examples\introduction.clj in every directory (or jar file) in the class
path. The error you got is an indication that no matching file could be
found.

On windows, the paths are delimited with semicolons, but on most other
platforms colons are used. That's why most examples will use colons. If the
paths in the class path contains spaces or other special characters, you
should enclose the thing in spaces, like this:

java -cp C:\path one\;C:\path two\ clojure.main

From what I can tell, Rob's example should work. I'm not sure if a trailing
backslash is required for directories, but you could try with and without it
to see if it makes any difference. If that doesn't work, try renaming
projects.clj to something without a dot in it. Also, look carefully for
typos...

I hope this helps...

// raek

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

Re: Enhanced Primitive Support

2010-06-19 Thread Mike Meyer

Nicolas Oury nicolas.o...@gmail.com wrote:

On the other hand, having boxed by default is a very significant slowdown
(10% on the strange program I tried, that had already a lot of annotations,
probably 20% or more on most programs), that can never be addressed : you
can't write annotations on every single line of your program.

Were those real world programs, or arithmetic benchmarks? Most real world 
programs I see spend so little of their time doing arithmetic that making the 
math an order of magnitude slower wouldn't make a noticeable difference in 
overall runtime.

Which puts making numbers primitives by default squarely in the realm of 
premature optimization.
-- 
Sent from my Android phone with K-9 Mail. Please excuse my brevity.

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


Re: Enhanced Primitive Support

2010-06-19 Thread Nicolas Oury
I tried it on my program. Very few arithmetic, most of it with annotation.
10%.
On an arithmetic benchmark, it would be in te *10/*20 range.
This 10% is orthogonal to what profiling shows. It just makes a lot of
little improvements spread everywhere.
That's why it couldn't be solved with annotation.


On Sat, Jun 19, 2010 at 10:13 AM, Mike Meyer 
mwm-keyword-googlegroups.620...@mired.org wrote:


 Nicolas Oury nicolas.o...@gmail.com wrote:

 On the other hand, having boxed by default is a very significant slowdown
 (10% on the strange program I tried, that had already a lot of
 annotations,
 probably 20% or more on most programs), that can never be addressed : you
 can't write annotations on every single line of your program.

 Were those real world programs, or arithmetic benchmarks? Most real world
 programs I see spend so little of their time doing arithmetic that making
 the math an order of magnitude slower wouldn't make a noticeable difference
 in overall runtime.

 Which puts making numbers primitives by default squarely in the realm of
 premature optimization.
 --
 Sent from my Android phone with K-9 Mail. Please excuse my brevity.

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


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

Re: Enhanced Primitive Support

2010-06-19 Thread Mike Meyer

Nicolas Oury nicolas.o...@gmail.com wrote:

I tried it on my program. Very few arithmetic, most of it with annotation.
10%

Can we see the source?
-- 
Sent from my Android phone with K-9 Mail. Please excuse my brevity.

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


Re: Enhanced Primitive Support

2010-06-19 Thread Nicolas Oury
yes, when it will be released :-b.
I can describe it though:
it applied a stochastically a set of rewriting rules on trees (represented
by records of records).
To speed up,  the activity of the rules in each subtree is cached in a Java
weak hash table from one step to another.
 There is a bit of arithmetic involved everywhere, and around 2-3 double
operations per function in the part choosing the instance of rule to apply.

On Sat, Jun 19, 2010 at 10:28 AM, Mike Meyer 
mwm-keyword-googlegroups.620...@mired.org wrote:


 Nicolas Oury nicolas.o...@gmail.com wrote:

 I tried it on my program. Very few arithmetic, most of it with annotation.
 10%

 Can we see the source?
 --
 Sent from my Android phone with K-9 Mail. Please excuse my brevity.

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


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

Re: Enhanced Primitive Support

2010-06-19 Thread Jules
I know nothing about the JVM, but I do know that on x86 you can handle
fixnum - bignum promotion fairly cheaply. You compile two versions of
the code: one for bignums and one for fixnums. After an arithmetic
instruction in the fixnum code you check if it overflowed, and if it
did you switch to the bignum code.

while(n  10) {
  n = n + 1;
}

=

while(n # 10) {
   a = n #+ 1;
   if(overflow){ n = ToBignum(n); goto foo; }
   n = a;
}

while(n.lessthan(10)) {
foo:
   n = n.add(1);
}

where # and #+ are the fixnum versions of  and +, and lessthan and
add are the bignum versions. Yeah it's slower than ignoring the
overflow, but faster than tagged 31-bit fixnums and a whole lot faster
than bignums. Can you convince the JVM to produce similar code?

Jules

On Jun 19, 4:22 am, Rich Hickey richhic...@gmail.com wrote:
 On Jun 18, 2010, at 10:18 PM, Mark Fredrickson wrote:

  So far most of the action has concerned arithmetic ops (+, -, *, /).
  Will these new semantics include the bit-shift operators? I vote yes.
  My use cases for bit ops would benefit from primitive ops.

  On a related note, my use cases call for silent overflow of bit shifts
  (pseudo random number generators). Will there be a way to disable
  overflow exceptions (either via a binding or through unchecked-*
  functions)?

 Yes, bit-ops will be made to align with whatever is done here.

 Rich





  On Jun 18, 8:33 pm, Rich Hickey richhic...@gmail.com wrote:
  Turnabout is fair play, so I've produced a version that swaps the
  defaults, still in the 'equal' branch:

  Docs:

 https://www.assembla.com/wiki/show/b4-TTcvBSr3RAZeJe5aVNr/
  Enhanced_Pr...

  Code:

 http://github.com/richhickey/clojure/commit/
  310534b8e7e7f28c75bb122b4...

  You can get the older arbitrary-precision default with this commit:

 http://github.com/richhickey/clojure/commit/
  7652f7e935684d3c7851fbcad...

  I've also temporarily enabled a diagnostic (in both) that tells you
  when you have a mismatch between a loop initializer and its recur
  form. It goes off over a hundred times in Clojure itself, when using
  the arbitrary precision default. In each case, the recur value is
  needlessly being boxed, every iteration of a loop, for loops that  
  will
  never be bigints; indexes, counters etc. I expect this will be very
  typical of most code. But removing that useless overhead would be a
  lot of tedious work.

  With the defaults swapped, only 2 warnings.

  Pay for what you use ...

  Rich

  On Jun 18, 4:52 pm, Rich Hickey richhic...@gmail.com wrote:

  I've revised and enhanced the strategy, based upon the feedback  
  here.
  I think it is a nice compromise.

  Docs (see update section at the top)

 https://www.assembla.com/wiki/show/b4-TTcvBSr3RAZeJe5aVNr/Enhanced_Pr
  ...

  Code:

 http://github.com/richhickey/clojure/commit/c79d28775e06b196ae1426f6c
  ...

  Thanks to all for the feedback, keep it coming!

  Rich

  On Jun 17, 2010, at 4:13 PM, Rich Hickey wrote:

  I've been doing some work to enhance the performance, and unify the
  semantics, of primitives, in three branches. I've started to  
  document
  this work here:

 https://www.assembla.com/wiki/show/clojure/Enhanced_Primitive_Support

  Feedback welcome,

  Rich

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

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


Re: Enhanced Primitive Support

2010-06-19 Thread Heinz N. Gies

On Jun 19, 2010, at 4:12 , Rich Hickey wrote:
 I have to say I'm in the 'pay for what you use' camp - you need a box, you 
 ask for one. If I don't (and neither do any of those loops), why should I 
 have to do extra work to avoid it?

- 42

I totally and wholeheartedly disagree, as long as there is a chance something 
goes wrong, and here is a lot of it, the default can not be we force people to 
know more - for example that they explicitly need to box things. And it is not 
even about longs and BigInts, doubles and Floats or what the java version means 
also come into play, how often do you mixed calculations because initializing 1 
is shorter and more used for you then 1.0? This will now break your loop, make 
it crumble into dust and give you odd, unexpected and wrong results.

Lets get away from the argument already cast and bring a new one. It is an 
impossible situation that the literal 1 in one place has a different meaning 
and behavior then in another place. This is in fact a show stopper, I'm 
serious, this would be worst then java.

(* 1 0.2) - works fine

but

(loop [n 1 r 1](if (zero? n) r (recur (dec n) (* r 0.2

does not because the 1 there is not the 1 in the upper example, that is so 
utterly wrong and horrible please think about it and think about how you'd sell 
someone he has to know where a literal means what, I can guarantee you this 
will keep many people from this wonderful language :(.

The default case for a language has to be the most intuitive version otherwise 
you end up with a mess of complex rules and special cases. It was said before, 
this is premature optimization in it's worst since it is forced on the user if 
they want or not. The priority has to be 'it works' later if it matters we can 
worry about 'it is fast' but this isn't working any more. 

Regards,
Heinz

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

2010-06-19 Thread nickikt
For such a young language it has a big momentum. Did Scala have that
after 2 years?

On 18 Jun., 23:56, cageface milese...@gmail.com wrote:
 Quick disclaimer - there are a lot of things I like in Scala and I
 think Odersky  crew have done some very impressive work bringing
 functional language concepts to the VM and giving Java developers a
 path forward. I also don't think Clojure vs x language battles are
 very productive and don't want to encourage one.

 Anyway, I imagine my trajectory as a developer over the last 10  years
 is pretty typical. I started out doing Java stuff but fell in love
 with Ruby and Rails in 2004 and have been working almost entirely in
 Ruby since. The idea that all that heavy, cumbersome Java cruft could
 in many cases be dispensed with was a revelation and the discovery
 that I could build software in a language that offered *no* compile
 time error checking that was still robust was a very pleasant
 surprise.

 Like a lot of Ruby hackers though, I also saw some warts in the
 language and also remained curious about other approaches. Also like a
 lot of Ruby hackers, the recent rise of new JVM languages has piqued
 my interest, particularly Scala and Clojure. Scala seemed like a more
 natural step from Ruby and my first experiences with it were
 encouraging. It seemed to offer a lot of the expressiveness of Ruby
 but with potentially much better performance and more robust runtime
 and, intriguingly, static type checking. However, after writing a
 handful of small but non-trivial programs in it the complexity lurking
 under the surface started peeking through and the intricacies of the
 type system and the significant complexity of the language itself
 became more apparent. It started to feel like a step back to the
 rigors of Java and heavyweight syntax and fights with the compiler.
 The predominant Scala web platform, Lift, also seemed to have a very
 heavy, enterprisey sort of correctness about it that felt
 overengineered.

 So I bounced over to Clojure and its clean, elegant core and minimal,
 flexible syntax seemed very refreshing. It felt much more in the
 liberal, malleable spirit of Ruby. The functional stuff was a bit of a
 stretch but it also seemed built on a simpler set of core concepts
 than the featureful but complex Scala collections.

 Unfortunately there seems to be a lot more commercial momentum for
 Scala though. It's still a blip compared to the mainstream languages
 but I'm seeing more and more job posts mentioning it, and hardly any
 for Clojure. I don't think Scala is a bad language overall, but I'm
 not sure I'd dump Ruby for it. On the other hand, I can imagine
 migrating most of my dev work over to Clojure with the right project.
 Has anybody else wrestled with this choice? Any thoughts?

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


Re: Enhanced Primitive Support

2010-06-19 Thread Michał Marczyk
On 19 June 2010 03:33, Rich Hickey richhic...@gmail.com wrote:
 Turnabout is fair play, so I've produced a version that swaps the
 defaults, still in the 'equal' branch:

The issue of which behaviour should be the default aside, I think that
I'd expect the *, + etc. ops to go with unannotated literals and the
primed variants to go with explicit hinting, whereas now this seems
not to be the case:

(defn fact [n]
  (loop [n (num n) r (num 1)]
  (if (zero? n)
  r
  (recur (dec n) (* r n)

This works for (fact 40), whereas the version with dec' and *' (and
the (num ...) still in place) doesn't; I'd expect this to be reversed.

In general, I'd expect the primed ops to be there for those who know
what they're doing; same goes for explicit hinting.

On 19 June 2010 04:12, Rich Hickey richhic...@gmail.com wrote:
 I have to say I'm in the 'pay for what you use' camp - you need a box, you
 ask for one. If I don't (and neither do any of those loops), why should I
 have to do extra work to avoid it?

The question is which desirable commodity Clojure programmers can
expect to get for free and which is to be obtainable through voluntary
banter: the sturdy boxes or the Potion of Speed +5. I'm used to paying
for the PoS, but a sudden rise in the price of boxes seems unwarranted
to me, especially if it only serves to lower the price of the PoS from
a (prim ...) hint where the local is introduced to zero. I mean, this
is no longer about the free lunch, it's more about the free
dessert which the power number crunchers surely do not need.

I have a hunch that if (num ...) stays in and primitive is the
default, people (I mean just about *everybody*) will only box things
in the face of the first crash or *maybe* after developing a great
intuitive feel for when that might be required. Of course there's
going to be a period of frantic learning about numeric representations
on the JVM etc. in between the crash and the boxing. And, um, whatever
for...?

Interestingly, the introductory materials on Clojure I've read so far
tout the don't worry about it quality of Clojure's numerics as a
benefit of the language. (The don't worry about it phrasing comes
from Programming Clojure.) I just mention this because I tend to
think it reasonable to present that as a benefit. The idea of making a
U-turn on this is surprising to me... Which is partly to say that I'm
still evaluating it, though so far my intuition stays pretty firmly on
the don't worry about it-is-good side.

TLDR summary: I'm very excited about the latest equal; I'd definitely
want the primed arithmetic ops to go with the hinted locals, whereas
non-primed (basic) variants would do the right thing for the simplest,
unhinted code (so which ops should get the primes in my eyes depends
on whether boxing of locals is the default); my heart is still on the
side of free sturdy boxes while I'm expecting to pay for the Potion of
Speed.

Sincerely,
Michał

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that 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: Problems with URL params and http-agent

2010-06-19 Thread Michael Wood
On 18 June 2010 23:54, Timothy Washington twash...@gmail.com wrote:
 That works, thanks. It's a bit weird because I did try just http encoding
 the parameters before. But I obviously encoded the wrong characters, or
 maybe used the wrong character encoding. Hmmm.

 Thanks :)

No problem :)

-- 
Michael Wood esiot...@gmail.com

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


Re: Enhanced Primitive Support

2010-06-19 Thread David Powell


Personally, I have no real interest in bigints, but I'm glad that they
are there, and that arithmetic code supports them polymorphically.

I'm not sure what I think regarding non-promoting numeric operators.
They are ok, but they seem to add complexity to the language, and they
don't look very newbie friendly. I think if we had them, promoting ops
should be the primed ones, and they would mostly be used in library
functions where performance is important.

  but
 (loop [n 1 r 1](if (zero? n) r (recur (dec n) (* r 0.2
 does not [work]

This seems to be particularly nasty. Clojure is statically typing r on
the assumption that just because the init value of r fits a primitive
int, that it can never be anything else.  Promoting operators do no
good, because the variable slot for the loop var has already been
assumed to be a primitive, so it isn't possible to promote it.

Is there any possibility that loop variables could be assumed to be
boxed numerics, unless type hinted to something else?

So:

  (loop [^int n 1 r 1](if (zero? n) r (recur (dec n) (* r 0.2


Numeric literals would still produce primitives where possible, but
would get auto-boxed in loop initialisers.

I think this option wouldn't have any nasty surprises.


-- 
Dave

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


Re: Enhanced Primitive Support

2010-06-19 Thread Heinz N. Gies

On Jun 19, 2010, at 14:18 , David Powell wrote:
 
  (loop [^int n 1 r 1](if (zero? n) r (recur (dec n) (* r 0.2
 
 
 Numeric literals would still produce primitives where possible, but
 would get auto-boxed in loop initialisers.
 
 I think this option wouldn't have any nasty surprises.
 
+41 (would be 42 if it were ^long since it is the clojure type I think)

This gives the option of make it fast if you know-what-you-are-doing(TM) which 
is great, and I certainly would use that myself :P but it still keeps the 
things simple and working for the default case.

Regards,
Heinz

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

Re: Enhanced Primitive Support

2010-06-19 Thread David Powell

 I think if we had them, promoting ops
 should be the primed ones, and they would mostly be used in library

Oops, I had meant the non-primed ops should support promotion. But
tbh, I have mixed feelings about promotion.

I haven't required bitint promotion myself, but having statically
typed numeric vars, where the type of the vars is chosen by Clojure
and it isn't obvious what that type is, seems potentially confusing.

It is the issue of loop initialisers fixing the types of the loop
variable slot that I'm more bothered about though.

-- 
Dave

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


Re: Enhanced Primitive Support

2010-06-19 Thread Rich Hickey


On Jun 18, 2010, at 11:47 PM, dmiller wrote:

Yes, it's easy to imagine a world where people who want efficient  
code
have to jump through hoops to get it. OTOH, you can just say (num  
some-

expr) to force it to be boxed, if you want assurance of an Object
initializer. Which will be the more common need?



From the wiki page Enhanced Primitive Support:  * Note: this means
that locals initialized with literals will have primitive type, e.g.
(let [x 42] …), and especially: (loop [x 42] …). If you intend to
recur with a non-primitive, init like this, (loop [x (num 42)] …)


I'd like to ask for some consideration on any use of (num x).   On the
CLR side, it is unimplementable as documented, there being no
equivalent in the CLR to Number.  If a proposed use of num can be
satisfied by this definition of num:

(defn num {tag :object} [x] x)

I can manage. I imagine this to be the case, but haven't had time to
read all the new code.

If you really mean to use a type that is a base type for all the
primitive numeric types -- not going to happen on the CLR.



Yes, that's a bit Java-ish. All we care about here is returning the  
canonic boxed representation of the number.


Rich

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


Re: Enhanced Primitive Support

2010-06-19 Thread Rich Hickey


On Jun 19, 2010, at 6:39 AM, Jules wrote:


I know nothing about the JVM, but I do know that on x86 you can handle
fixnum - bignum promotion fairly cheaply. You compile two versions of
the code: one for bignums and one for fixnums. After an arithmetic
instruction in the fixnum code you check if it overflowed, and if it
did you switch to the bignum code.

while(n  10) {
 n = n + 1;
}

=

while(n # 10) {
  a = n #+ 1;
  if(overflow){ n = ToBignum(n); goto foo; }
  n = a;
}

while(n.lessthan(10)) {
foo:
  n = n.add(1);
}

where # and #+ are the fixnum versions of  and +, and lessthan and
add are the bignum versions. Yeah it's slower than ignoring the
overflow, but faster than tagged 31-bit fixnums and a whole lot faster
than bignums. Can you convince the JVM to produce similar code?



You can do things like that in a closed world of a few operators and  
types (although it gets unwieldy as the number of variables goes up).  
And of course, inside the math ops Clojure already does things like  
that.


But that is not what we are dealing with here. This is an open system,  
where representational issues of functions, arguments and returns come  
into play. The 'operators' +, - etc are actually function calls - they  
are not special to the compiler. And your loop may also contain other  
function calls:


while(n  10) {
 foo(n)
 n = n + 1;
}

how do I know foo can handle the bigint once I've upgraded?

How about this?

while(n  10) {
 n = foo(n)
}

Unless you have a tagged architecture you can't have boxed/unboxed arg/ 
return uniformity (and even then you lose some bits of range).


Rich

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


Re: Enhanced Primitive Support

2010-06-19 Thread Rich Hickey


On Jun 19, 2010, at 6:41 AM, Heinz N. Gies wrote:



On Jun 19, 2010, at 4:12 , Rich Hickey wrote:
I have to say I'm in the 'pay for what you use' camp - you need a  
box, you ask for one. If I don't (and neither do any of those  
loops), why should I have to do extra work to avoid it?


- 42

I totally and wholeheartedly disagree, as long as there is a chance  
something goes wrong, and here is a lot of it, the default can not  
be we force people to know more - for example that they explicitly  
need to box things. And it is not even about longs and BigInts,  
doubles and Floats or what the java version means also come into  
play, how often do you mixed calculations because initializing 1 is  
shorter and more used for you then 1.0? This will now break your  
loop, make it crumble into dust and give you odd, unexpected and  
wrong results.


Lets get away from the argument already cast and bring a new one. It  
is an impossible situation that the literal 1 in one place has a  
different meaning and behavior then in another place. This is in  
fact a show stopper, I'm serious, this would be worst then java.


(* 1 0.2) - works fine

but

(loop [n 1 r 1](if (zero? n) r (recur (dec n) (* r 0.2

does not because the 1 there is not the 1 in the upper example, that  
is so utterly wrong and horrible please think about it and think  
about how you'd sell someone he has to know where a literal means  
what, I can guarantee you this will keep many people from this  
wonderful language :(.


As I told Mark, this was, and will again be, a hard error.

I am telling you though, if you continue with these show stopper,  
will keep people from using Clojure sky-is-falling histrionics, I  
will stop reading your messages.


Rich

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


Re: Enhanced Primitive Support

2010-06-19 Thread cageface
Maybe it's only because I'm coming from Ruby, in which number
promotion is automatic and everything is slow, but if I have to choose
between correctness and performance as a *default*, I'll choose
correctness every time. I think there's a good reason that GCC, for
instance, makes you push the compiler harder with compiler flags if
you want to squeeze extra performance out of a program and accept the
corresponding brittleness that it often brings. I also always thought
that the transparent promotion of arithmetic was one of the strongest
selling points of Common Lisp.

My impression has always been that performance of numerics is rarely
the bottleneck in typical code (web stuff, text processing, network
code etc), but that unexpected exceptions in such code are the source
of a lot of programmer heartache. On the other hand, I think 99% of
the cases in which I've had a number exceed a 64 bit value were also
examples of errors that might as well have been exceptions because
they indicated a flaw in the code.

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


Re: Enhanced Primitive Support

2010-06-19 Thread David Nolen
On Sat, Jun 19, 2010 at 5:13 AM, Mike Meyer 
mwm-keyword-googlegroups.620...@mired.org wrote:


 Were those real world programs, or arithmetic benchmarks? Most real world
 programs I see spend so little of their time doing arithmetic that making
 the math an order of magnitude slower wouldn't make a noticeable difference
 in overall runtime.


Most real world programs. You mean like Clojure itself?

Please look over the implementation of gvec before making statements like
this:

  clojure.lang.IPersistentCollection
  (cons [this val]
 (if ( (- cnt (.tailoff this)) (int 32))
  (let [new-tail (.array am (inc (.alength am tail)))]
(System/arraycopy tail 0 new-tail 0 (.alength am tail))
(.aset am new-tail (.alength am tail) val)
(new Vec am (inc cnt) shift root new-tail (meta this)))
  (let [tail-node (VecNode. (.edit root) tail)]
(if ( (bit-shift-right cnt (int 5)) (bit-shift-left (int 1) shift))
;overflow root?
  (let [new-root (VecNode. (.edit root) (object-array 32))]
(doto ^objects (.arr new-root)
  (aset 0 root)
  (aset 1 (.newPath this (.edit root) shift tail-node)))
(new Vec am (inc cnt) (+ shift (int 5)) new-root (let [tl
(.array am 1)] (.aset am  tl 0 val) tl) (meta this)))
  (new Vec am (inc cnt) shift (.pushTail this shift root tail-node)
 (let [tl (.array am 1)] (.aset am  tl 0 val) tl) (meta
this))


David

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

Re: labrepl isn't a project in netbeans 6.8 - (Ubuntu 10.04)

2010-06-19 Thread Aaron Bedra
Jared,

There was another post about issues with netbeans.  I am looking into why
this is happening.  On another note, labrepl uses clojure 1.2, but that is
all handled via leiningen.

Cheers,

Aaron

On Thu, Jun 17, 2010 at 11:10 PM, Jared tri...@gmail.com wrote:

 I was following the instructions to get labrepl up and running and hit
 a snag. Netbeans does not recognize Samples/Clojure/Relevance
 LabReplProject as a project. After creating it it does not appear in
 the Projects window. So I go to File - Open Project and click on
 RelevanceLabRepl and hit Open Project. Instead of opening the project
 it displays the subfolders. Also, when RelevanceLabRepl is selected it
 does not display a name for Project Name:, and the box Open as Main
 Project is grayed out.

 I do have a normal clojure project that I can open. I am using clojure
 1.0 if that matters.

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

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

Re: Enhanced Primitive Support

2010-06-19 Thread Nicolas Oury
I definitely would like to see more people trying their code with primitive
by default and talk about unexpected bugs and performance improvements.


On Sat, Jun 19, 2010 at 3:43 PM, David Nolen dnolen.li...@gmail.com wrote:


 Most real world programs. You mean like Clojure itself?


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

what replaces clojure.parallel?

2010-06-19 Thread Albert Cardona
Hi all,

The http://clojure.org/other_libraries web page states that:

Parallel Processing
The parallel library (namespace parallel, in parallel.clj) wraps the
ForkJoin library. This lib is now deprecated.

If the clojure.parallel is deprecated, what replaces it?
Is it pcalls and pvalues in clojure.core?
What other parallel computation constructs exist in clojure 1.2 beyond
pmap, pcalls and pvalues?

Pointers very appreciated.

Albert
-- 
http://albert.rierol.net

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that 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: classpath and require

2010-06-19 Thread Rob Lachlan
I was wondering whether putting a dot in a directory on the classpath
makes a difference.  On OS X, the answer is no.  Unfortunately, I
don't have a windows machine, so I can't check for certain what the
situation is there.

Another issue: I ignored case-sensitivity in my answer above.  Are
windows paths ever case-sensitive?  (silly question, I know, but I
haven't worked with windows in a while.)  Another question:

If you run:

java -cp c:\clojure-contrib\clojure-contrib.jar;c:\clojure
\clojure.jar;c:\projects.clj\examples clojure.main

can you then just do (require 'introduction)

And do try it with quotes around the classpath.  The dot in
projects.clj might be like a space in that it could lead to a parsing
error without quotes.

Good luck
Rob

On Jun 19, 1:58 am, Rasmus Svensson r...@lysator.liu.se wrote:
 2010/6/18 Mohammad Khan beepl...@gmail.com





  C:\Projects.cljjava -cp
  c:\clojure-contrib\clojure-contrib.jar;c:\clojure\clojure.jar clojure.main
  Clojure 1.1.0-alpha-SNAPSHOT
  user= (require 'examples.introduction)
  java.io.FileNotFoundException: Could not locate
  examples/introduction__init.class or examples/introduction.clj on
  classpath:  (NO_SOURCE_FILE:0)
  user=

  C:\Projects.cljecho %CLASSPATH%
  C:\Projects.clj;C:\clojure;C:\clojure-contrib
  C:\Projects.cljdir examples\introduction.clj
   Volume in drive C is xxx
   Volume Serial Number is -
   Directory of C:\Projects.clj\examples

  06/18/2010  04:52 PM                40 introduction.clj
                 1 File(s)             40 bytes
                 0 Dir(s)  xx,xxx,xxx bytes free

  C:\Projects.clj

 Hello!

 To me it looks like you have gotten the most things right. As I see you
 understand, you must have clojure, clojure-contrib and the source on the
 class path. However, how these are specified can be a bit tricky. There are
 basically two cases: directories and jar files.

 When using jar files, the jar file itself must be in the class path, not the
 directory which contains it. In our case, the entries would be
 c:\clojure\clojure.jar and c:\clojure-contrib\clojure-contrib.jar, just as
 you wrote.

 When using folders with clojure source files or ahead-of-time compiled
 classes, the directory that contains the folder that represents the topmost
 component of the namespace. For example, in your case the namespace
 examples.introduction is stored in the file
 C:\Projects.clj\examples\introduction.clj so the directory C:\Projects.clj\
 should be inlcuded in the class path.

 When Clojure loads the namespace examples.introduction, it will try to find
 examples\introduction.clj in every directory (or jar file) in the class
 path. The error you got is an indication that no matching file could be
 found.

 On windows, the paths are delimited with semicolons, but on most other
 platforms colons are used. That's why most examples will use colons. If the
 paths in the class path contains spaces or other special characters, you
 should enclose the thing in spaces, like this:

 java -cp C:\path one\;C:\path two\ clojure.main

 From what I can tell, Rob's example should work. I'm not sure if a trailing
 backslash is required for directories, but you could try with and without it
 to see if it makes any difference. If that doesn't work, try renaming
 projects.clj to something without a dot in it. Also, look carefully for
 typos...

 I hope this helps...

 // raek

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


Re: Enhanced Primitive Support

2010-06-19 Thread Rich Hickey

The hard error has been restored:

http://github.com/richhickey/clojure/commit/25165a9ccd1001fa7c4725a8219c4108803ae834

Rich

On Jun 19, 2010, at 2:03 AM, Mark Engelberg wrote:


I'm confused.  In the latest scheme, what is the eventual plan for
handling a recur to a loop element that was initialized with a
primitive?  Are boxed numbers automatically coerced to the primitive?
Would a long be coerced to a double, or double to long?  Under what
scenarios will you get a warning, and when will you get an error?

I think what troubles me the most about this loop/recur issue is that
the semantics of recur depend completely on whether a variable is
assigned a primitive or boxed numeric type.  To know what the recur
will do, you must know the type of the assigned value.  This has
always been the case, but in the current version of Clojure, provided
you aren't using Java interop, it's relatively straightforward to
know.  Unless the variable or literal is explicitly cast to a
primitive, it's not a primitive.  But now, with the advent of static
functions which can return primitives, it becomes more likely to not
easily be able to determine this fact.  If I say (loop [x (foo 2)]...)
I have no way of knowing what's going to happen when I recur.  Yes, I
realize that you can run the function and use warnings/errors to find
out.  But I find it unsettling to have a commonly used code form with
semantics I can't predict just by looking at it.

It's attractive that the current proposal gives speed benefits to
common cases with no additional annotation.  But I personally place a
higher value on being able to understand the semantics of my code when
reading through it.  I would prefer a version where loop requires some
sort of explicit annotation on a variable if you want it to require a
primitive upon recur.  (Ideally, I'd probably want the annotation on
the variable using a syntax that mirrors static functions, rather than
the old technique of typecasting the initializer, since the whole
typecasting system makes less sense now that literals and certain
return values are already primitives.  Unifying the syntax and
semantics of using primitives in loops with the syntax and semantics
of using primitives as inputs to static functions makes a lot of sense
to me.)

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

Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient  
with your first post.

To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


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


Re: classpath and require

2010-06-19 Thread Michael Wood
On 19 June 2010 17:46, Rob Lachlan robertlach...@gmail.com wrote:
 I was wondering whether putting a dot in a directory on the classpath
 makes a difference.  On OS X, the answer is no.  Unfortunately, I
 don't have a windows machine, so I can't check for certain what the
 situation is there.

No, rzezeski found the problem.

Mohammad's CLASSPATH environment variable was correct, but he was
overriding that by using:
java -cp clojure-contrib.jar;clojure.jar clojure.main

-- 
Michael Wood esiot...@gmail.com

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


Re: Clojure script in the classpath

2010-06-19 Thread Chas Emerick
If you're just looking to run a script that happens to be on the  
classpath, you can do so by prepending an '@' character to the  
classpath-relative path to the script.


So, if a directory foo is on your classpath, and a clojure file you'd  
like to run is at foo/bar/script.clj, then you can run it with:


java -cp your_classpath_here clojure.main @/bar/script.clj

FWIW, this is noted in the documentation for clojure here:

http://clojure.org/repl_and_main

Cheers,

- Chas

On Jun 18, 2010, at 6:15 PM, Paul Moore wrote:


I've just seen a couple of postings which, if I'm not mistaken, imply
that it's possible to have a Clojure script in my classspath. Is that
right? I come from a Python background (little or no Java experience)
and the idea that anything other than .class or .jar files (or
directories) could be on the classpath never occurred to me.

Can anyone give me a complete example of how this works? (I probably
need to get the file names and namespaces right, something I'm still
struggling with - again the Java/JVM requirements for filenames that
match classnames is a new concept for me).

Could I have found anything about this on the web? The Java
documentation (http://java.sun.com/javase/6/docs/technotes/tools/windows/classpath.html 
)

didn't mention anything other than classes/jars/zips/directories, and
my Google skills didn't turn up anything clojure-specific.

Thanks,
Paul.

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

To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


--
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that 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: classpath and require

2010-06-19 Thread Mohammad Khan
Correction, it worked..


On Fri, Jun 18, 2010 at 6:19 PM, Mohammad Khan beepl...@gmail.com wrote:

 No, it didn't work.. what else I could be missing..


 On Fri, Jun 18, 2010 at 5:56 PM, Rob Lachlan robertlach...@gmail.comwrote:

 Whoops, that should read:

 java -cp c:\clojure-contrib\clojure-contrib.jar;c:\clojure
 \clojure.jar;c:
 \projects.clj clojure.main

 On Jun 18, 2:51 pm, Rob Lachlan robertlach...@gmail.com wrote:
  have you tried starting with:
 
  c:\clojure-contrib\clojure-contrib.jar;c:\clojure\clojure.jar;c:
  \projects.clj clojure.main
 
  On Jun 18, 2:00 pm, Mohammad Khan beepl...@gmail.com wrote:
 
 
 
   C:\Projects.cljjava -cp
   c:\clojure-contrib\clojure-contrib.jar;c:\clojure\clojure.jar
 clojure.main
   Clojure 1.1.0-alpha-SNAPSHOT
   user= (require 'examples.introduction)
   java.io.FileNotFoundException: Could not locate
   examples/introduction__init.class or examples/introduction.clj on
   classpath:  (NO_SOURCE_FILE:0)
   user=
 
   C:\Projects.cljecho %CLASSPATH%
   C:\Projects.clj;C:\clojure;C:\clojure-contrib
   C:\Projects.cljdir examples\introduction.clj
Volume in drive C is xxx
Volume Serial Number is -
Directory of C:\Projects.clj\examples
 
   06/18/2010  04:52 PM40 introduction.clj
  1 File(s) 40 bytes
  0 Dir(s)  xx,xxx,xxx bytes free
 
   C:\Projects.clj

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




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

Re: Enhanced Primitive Support

2010-06-19 Thread Daniel
Checked out the new prim branch to repeat some tests.


user= (defn ^:static fib ^long [^long n]
  (if (= n 1)
1
(+ (fib (dec n)) (fib (- n 2)
#'user/fib
user= (time (fib 38))
Elapsed time: 4383.127343 msecs
63245986

That's certainly not what I expected


user= (defn fact [n] (loop [n n r 1] (if (zero? n) 1 (recur (dec' n)
(*' r n)
#'user/fact
user= (fact 40)
java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to
java.lang.Number (NO_SOURCE_FILE:7)


Neither is this.  According to the docs long-and-smaller integers
promote in all cases, even when given integer primitives with the
prime ops.

Something I did wrong?

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


Records forget they are records

2010-06-19 Thread Oscar Forero
Hello,

I am working with Clojure for a university project and hit this
problem

http://paste.pocoo.org/show/227239/

I am trying to defines symbols from a map with keywords as keys and X
as value (where X is usually a lambda or a Record), the first example
does that ...

(binder data)

Creates the definitions but the record loose the Record type
information.

Using a macro works but I can not operated on the whole collection,
have tried multiple options including doseq but all hit different
issues.

From the chat it seems that a record evals to map and is the reason
why the function approach fails (thx AWizzArd). Is this intended or
did I just hit an under construction sign?

Any suggestions?

best regards,

Oscar

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that 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: classpath and require

2010-06-19 Thread Mohammad Khan
Yes, exactly it was, also at some point I was trying examples/introduction
(ruby's require like statement) instead of examples.introduction which all
together made me lost. Thanks everybody for your help.

Thanks,
Mohammad


On Sat, Jun 19, 2010 at 11:59 AM, Michael Wood esiot...@gmail.com wrote:

 On 19 June 2010 17:46, Rob Lachlan robertlach...@gmail.com wrote:
  I was wondering whether putting a dot in a directory on the classpath
  makes a difference.  On OS X, the answer is no.  Unfortunately, I
  don't have a windows machine, so I can't check for certain what the
  situation is there.

 No, rzezeski found the problem.

 Mohammad's CLASSPATH environment variable was correct, but he was
 overriding that by using:
 java -cp clojure-contrib.jar;clojure.jar clojure.main

 --
 Michael Wood esiot...@gmail.com

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


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

Re: labrepl isn't a project in netbeans 6.8 - (Ubuntu 10.04)

2010-06-19 Thread kredaxx
Find the Maven plugin in the NB's plugin section and install if you
don't have it. It *might* help. At least that's what fixed it for my
NB installation.

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


Re: Enhanced Primitive Support

2010-06-19 Thread Rich Hickey


On Jun 19, 2010, at 4:25 AM, Daniel wrote:


Checked out the new prim branch to repeat some tests.


user= (defn ^:static fib ^long [^long n]
 (if (= n 1)
   1
   (+ (fib (dec n)) (fib (- n 2)
#'user/fib
user= (time (fib 38))
Elapsed time: 4383.127343 msecs
63245986

That's certainly not what I expected


user= (defn fact [n] (loop [n n r 1] (if (zero? n) 1 (recur (dec' n)
(*' r n)
#'user/fact
user= (fact 40)
java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to
java.lang.Number (NO_SOURCE_FILE:7)


Neither is this.  According to the docs long-and-smaller integers
promote in all cases, even when given integer primitives with the
prime ops.

Something I did wrong?


Yes, you are in the wrong branch. Get the 'equal' branch.

Rich

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


need help understanding two issues

2010-06-19 Thread Albert Cardona
Hi all,

I have run into the following two issues over the last few days. I
would appreciate insight/help/advice:


1. How come APersistentMap$KeySet doesn't implement IPersistentSet?

(clojure.set/intersection (keys {2 two 4 four}) #{2 3})

 java.lang.ClassCastException: clojure.lang.APersistentMap$KeySeq
cannot be cast to clojure.lang.IPersistentSet


So one must:

(clojure.set/intersection (set (keys {2 two 4 four})) #{2 3})

... which is redundant. Is there a better way?


2. I can't get clojure.set/project to work. All of the following throw
an exception:

(clojure.set/project (keys {2 two 4 four}) #{2 3})
(clojure.set/project (set (keys {2 two 4 four})) #{2 3})

Caused by: java.lang.ClassCastException: java.lang.Integer cannot be
cast to java.util.Map

... and this one returns a result that I don't understand:

(clojure.set/project {2 two 4 four} #{2 3})

#{{}}

So perhaps I have misread what xrel is supposed to be, in the docs
for clojure.set/project:

clojure.set/project
([xrel ks])
  Returns a rel of the elements of xrel with only the keys in ks

I understand that one should use select-keys to get the submap for a
given set of keys.
But how come the map's key set is not set that plays well with the
rest of clojure sets?



Help very appreciated.

Albert
-- 
http://albert.rierol.net

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


Re: Enhanced Primitive Support

2010-06-19 Thread Tim Daly


(proclaim (speed 3) (safety 0))

is verbose? Telling the compiler in one place that you care
about boxing speed, such as (declare (x unboxed)) seems to
me to be a very direct way to tell the compiler to choose
+' vs + everywhere that 'x' occurs.

This means that it just works code does not need additional
unboxing overhead. It also means that make it fast code is
marked in a single place.

And the form can be dynamically computed so you can adapt to
the platform.

It has the additional factor that common lispers will get it.

I understand that it does not fit with your current model of
using inline typing. For a pervasive change like fast numerics
the inline typing or library-based typing is, to my mind, a bit
more cumbersome than 'proclaim' and 'declare' but that's probably
because of my common lisp background. Type hinting feels to me
like using symbol-property machinery in common lisp.

In any case, keep up the good work. I'm impressed with Clojure.

Tim Daly

Rich Hickey wrote:


On Jun 19, 2010, at 2:50 AM, Tim Daly wrote:


Is it possible to follow the Common Lisp convention
of proclaim/declaim/declare in order to specify types?



It would be possible of course, but undesirable. We're trying to avoid 
that kind of verbosity.


Rich



--
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that 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: need help understanding two issues

2010-06-19 Thread Rob Lachlan
I'll take a whack at it.


 1. How come APersistentMap$KeySet doesn't implement IPersistentSet?

Because keys and vals are designed to return (lazy) sequences.  More
important, these two functions return those two sequences in the same
order.  The laziness avoids having to incur the overhead of creating
the set structure, though if you want that you can just call (set
(keys map)) as in your example.



 2. I can't get clojure.set/project to work. All of the following throw
 an exception:

 (clojure.set/project (keys {2 two 4 four}) #{2 3})
 (clojure.set/project (set (keys {2 two 4 four})) #{2 3})


Yeah, I found the doc confusing as well.  Here's an example:

user (ns user (:use clojure.set))
nil
user (project [{1 2, 2 4, 3 6}, {1 3, 2 6}] [1])
#{{1 3} {1 2}}

So project seems to take a collection of maps, and projects, or
restricts them all on to the values specified in the second argument.

Cheers
Rob

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


Re: Enhanced Primitive Support

2010-06-19 Thread Rich Hickey


On Jun 19, 2010, at 1:05 PM, Tim Daly wrote:



(proclaim (speed 3) (safety 0))

is verbose? Telling the compiler in one place that you care
about boxing speed, such as (declare (x unboxed)) seems to
me to be a very direct way to tell the compiler to choose
+' vs + everywhere that 'x' occurs.

This means that it just works code does not need additional
unboxing overhead. It also means that make it fast code is
marked in a single place.

And the form can be dynamically computed so you can adapt to
the platform.

It has the additional factor that common lispers will get it.

I understand that it does not fit with your current model of
using inline typing. For a pervasive change like fast numerics
the inline typing or library-based typing is, to my mind, a bit
more cumbersome than 'proclaim' and 'declare' but that's probably
because of my common lisp background. Type hinting feels to me
like using symbol-property machinery in common lisp.



I don't want to get into it here, but the CL model in this area is  
quite cumbersome and opaque, IMO.


What precisely will (proclaim (speed 3) (safety 0)) do?

And of course, that is never enough, this from the CL spec:

(defun often-used-subroutine (x y)
  (declare (optimize (safety 2)))
  (error-check x y)
  (hairy-setup x)
  (do ((i 0 (+ i 1))
   (z x (cdr z)))
  ((null z))
  ;; This inner loop really needs to burn.
  (declare (optimize speed))
  (declare (fixnum i))
  ))

The (declare (fixnum i)) above being pertinent to this discussion vis- 
a-vis verbosity.


Not to mention the wonderful 'the' (this also from the CL spec):

(let ((i 100)) (declare (fixnum i)) (the fixnum (1+ i))) = 101

N.B. that the declaration of the type of i does not cover the result  
of 1+, which needs its own declaration.


Never mind that trading runtime safety for speed is completely not on  
the table for Clojure. It is one of the great lies of CL that it is  
both safe and very fast. It is safe *or* very fast. Clojure code will  
remain verifiable and safe.


The CL model is not something I want to emulate in Clojure.

Point taken about the type hinting. OTOH, metadata type hints flow  
through macros, whereas the decoupled i and its declaration of the CL  
above are extremely difficult to transform together. Metadata flowing  
is really an enormous win, IMO.


Rich

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


Re: Enhanced Primitive Support

2010-06-19 Thread Daniel
On Jun 19, 11:45 am, Rich Hickey richhic...@gmail.com wrote:
 On Jun 19, 2010, at 4:25 AM, Daniel wrote:



  Checked out the new prim branch to repeat some tests.

  user= (defn ^:static fib ^long [^long n]
   (if (= n 1)
 1
 (+ (fib (dec n)) (fib (- n 2)
  #'user/fib
  user= (time (fib 38))
  Elapsed time: 4383.127343 msecs
  63245986

  That's certainly not what I expected

  user= (defn fact [n] (loop [n n r 1] (if (zero? n) 1 (recur (dec' n)
  (*' r n)
  #'user/fact
  user= (fact 40)
  java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to
  java.lang.Number (NO_SOURCE_FILE:7)

  Neither is this.  According to the docs long-and-smaller integers
  promote in all cases, even when given integer primitives with the
  prime ops.

  Something I did wrong?

 Yes, you are in the wrong branch. Get the 'equal' branch.

 Rich

Cool.  This works correctly now.  Super nice, too :)

user= (defn ^:static fib ^long [^long n]
  (if (= n 1)
1
(+ (fib (dec n)) (fib (- n 2)
#'user/fib
user= (time (fib 38))
Elapsed time: 601.563589 msecs
63245986


And this returns the error you specified:

user= (defn fac [n] (loop [n n r 1] (if (zero? n) 1 (recur (dec' n)
(*' r n)
java.lang.RuntimeException: java.lang.IllegalArgumentException:  recur
arg for primitive local: r is not matching primitive, had:
java.lang.Number, needed: long (NO_SOURCE_FILE:13)


Which is really poor behavior.  Having numeric literals default to
primitive types is great but this behavior does not match the
documentation.  To quote: long-and-smaller integers promote in all
cases, even when given integer primitives with the prime ops.  Any
behavior other than that is confusing and essentially means the
programmer cannot have dependable bindings (to be fair, boxing at the
start of the loop fixes it but whatever).  I fully acknowledge that
the reason I don't understand 'primitive-by-default locals' may be
because I'm so new at Clojure (and functional programming), so take
this suggestion with a grain of salt: locals should default to the
type specified in code (which means the prime ops should cause the
rebind to auto-box/upgrade like the documentation dictates) or have
sensible defaults (like literals default to primitives (which is
awesome!)).  At least that makes sense to me in a dynamic context.


 Really? It seems tedious to me.  Don't you get tired of saying int i =
 42 in Java, when you know full well the compiler knows 42 is an int? I
 do, and Clojure is competing with languages that infer the right types
 without the redundancy.

Agree 100%, which is partly why this silly loop/recur behavior needs
to be fixed.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that 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: Basic toolset for non-Java programmer

2010-06-19 Thread Paul Moore
Thanks to Ryan, Rob and Alex for the suggestions. I'll have a deeper
look into all of them.
Paul

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


Re: Clojure script in the classpath

2010-06-19 Thread Paul Moore
On 19 June 2010 07:24, rzeze...@gmail.com rzeze...@gmail.com wrote:
 On Jun 18, 6:15 pm, Paul Moore p.f.mo...@gmail.com wrote:
 I've just seen a couple of postings which, if I'm not mistaken, imply
 that it's possible to have a Clojure script in my classspath. Is that
 right?

 Yes, you can have .clj files on your classpath.  In fact, you can
 pretty much have anything on your classpath.  Checkout
 java.lang.ClassLoader 
 http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ClassLoader.html#getResource(java.lang.String)
 .  This is what Clojure uses under the covers.

Thanks! (And thanks for the rest of your comments). I'll look into
this a bit more. I think that my experiments were failing because I
had the namespaces wrong - thanks for the pointer.

Paul.

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


Re: Clojure script in the classpath

2010-06-19 Thread Paul Moore
On 19 June 2010 17:22, Chas Emerick cemer...@snowtide.com wrote:
 If you're just looking to run a script that happens to be on the classpath,
 you can do so by prepending an '@' character to the classpath-relative path
 to the script.

 So, if a directory foo is on your classpath, and a clojure file you'd like
 to run is at foo/bar/script.clj, then you can run it with:

 java -cp your_classpath_here clojure.main @/bar/script.clj

 FWIW, this is noted in the documentation for clojure here:

 http://clojure.org/repl_and_main

Nice! Thanks.
Paul.

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


Re: Enhanced Primitive Support

2010-06-19 Thread Mark Engelberg
On Sat, Jun 19, 2010 at 6:32 AM, Rich Hickey richhic...@gmail.com wrote:
 Really? It seems tedious to me.  Don't you get tired of saying int i = 42 in
 Java, when you know full well the compiler knows 42 is an int? I do, and
 Clojure is competing with languages that infer the right types without the
 redundancy.

In this case, the question isn't so much whether Clojure can figure
out that 42 is a primitive or boxed integer.  The question is whether
the programmer wants to insist that, upon recurrence, the
primitiveness must match the initial binding.  Right now, Clojure
makes the determination about what the recurrence needs to be based on
the initial binding, so it becomes paramount for the programmer to
understand the type of that initial binding.  But conceivably there
are other ways that Clojure could make a determination about what kind
of loop/recur behavior you want other than the type of the initial
binding.  So an alternative way to think about this is to relax the
restriction that a recur must match the primitiveness of the loop
binding, but allow the programmer to somehow control whether they want
this primitive-matching behavior or not.  Ideally, the behavior of
recur should be readily apparent from inspection of the code.
Unfortunately, the type of the initial binding is not always clear,
which suggests to me that another scheme would be preferable.

Sadly, I don't have any idea right now on how to cleanly specify the
desired loop/recur behavior other than something that looks a lot like
type annotations.  But thinking of it in this way opens up the
possibility of other solutions (such as a loop' construct), so maybe
brainstorming along these lines will be useful.  I agree with another
poster that the holy grail would be if loop/recur automagically gave
performance benefits when recurring with a primitive that matched the
initial binding, but if you recur with something else, it just
gracefully rolls over to a boxed version of the whole loop.  Given
that Java has no way of expressing that something can be a primitive
or an Object, this seems unlikely to be possible, but perhaps with
that ideal in mind, some approximation can be found.

 Again, it is a matter of defaults, the non-default is going to have to be
 explicit, and you can just as easily be explicit that you want the loop
 argument to be an Object, either with (loop [^Object i 42] ...), (loop [i
 (num 42)] ...) or your (loop' [i 42] ...) idea.

Agreed, but with a default of boxing, it is possible to write all code
without ever using an annotation -- it will just be a bit slower than
it could be.  With a default of primitives, there is ordinary code
that won't work properly unless you dig deeper into Clojure and learn
all about explicit boxing and figure out when and where to use it.  I
prefer the default where I can ignore tedious type annotations and my
code just works.

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


Re: Enhanced Primitive Support

2010-06-19 Thread Nicolas Oury
Not ordinary code. 10^19 is big.

On Sat, Jun 19, 2010 at 8:08 PM, Mark Engelberg mark.engelb...@gmail.comwrote:


 Agreed, but with a default of boxing, it is possible to write all code
 without ever using an annotation -- it will just be a bit slower than
 it could be.  With a default of primitives, there is ordinary code
 that won't work properly unless you dig deeper into Clojure and learn
 all about explicit boxing and figure out when and where to use it.  I
 prefer the default where I c

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

Re: Enhanced Primitive Support

2010-06-19 Thread Jules
On Jun 19, 3:53 pm, Rich Hickey richhic...@gmail.com wrote:
 On Jun 19, 2010, at 6:39 AM, Jules wrote:





  I know nothing about the JVM, but I do know that on x86 you can handle
  fixnum - bignum promotion fairly cheaply. You compile two versions of
  the code: one for bignums and one for fixnums. After an arithmetic
  instruction in the fixnum code you check if it overflowed, and if it
  did you switch to the bignum code.

  while(n  10) {
   n = n + 1;
  }

  =

  while(n # 10) {
    a = n #+ 1;
    if(overflow){ n = ToBignum(n); goto foo; }
    n = a;
  }

  while(n.lessthan(10)) {
  foo:
    n = n.add(1);
  }

  where # and #+ are the fixnum versions of  and +, and lessthan and
  add are the bignum versions. Yeah it's slower than ignoring the
  overflow, but faster than tagged 31-bit fixnums and a whole lot faster
  than bignums. Can you convince the JVM to produce similar code?

 You can do things like that in a closed world of a few operators and  
 types (although it gets unwieldy as the number of variables goes up).  
 And of course, inside the math ops Clojure already does things like  
 that.

 But that is not what we are dealing with here. This is an open system,  
 where representational issues of functions, arguments and returns come  
 into play. The 'operators' +, - etc are actually function calls - they  
 are not special to the compiler. And your loop may also contain other  
 function calls:

 while(n  10) {
   foo(n)
   n = n + 1;

 }

 how do I know foo can handle the bigint once I've upgraded?

 How about this?

 while(n  10) {
   n = foo(n)

 }

 Unless you have a tagged architecture you can't have boxed/unboxed arg/
 return uniformity (and even then you lose some bits of range).

 Rich

There are two possibilities: either foo gets inlined and the same
optimization is applied to the inlined code. Or foo is not inlined and
then you pass the general boxed representation to foo (but inside foo
the same optimization will be applied).

Suppose that we have a boxed representation like this:

class Num { ... }
class Small {
  int val;
  Num add(int n){ // argument specialized to int for simplicity of
this example
int sum = val + n;
if(overflow) return val.toBig().add(n);
else return new Small(sum);
  }
  ...
}
class Big {
  BigNum val;
  Num add(int n){ ... }
}

Now the while loop. I use functional notation because the control flow
is hairy and with while loops this leads to a lot of reorganization.
With functional notation it's easier to see that every step is simple
and mechanical.

Here's our while loop and the library function to add two numbers:

loop(n) = if p(n) then n else loop(add(n,1))
add(Small a, int b) = let sum = a.val+b in if overflow then
add(Big(a.val),b) else Small(sum)
add(Big a, int b) = bigAdd(a,b)

Inline add into the loop:

loop(Small n) = if p(n) then n else let sum = n.val+1 in if overflow
then loop(add(Big(n.val),1)) else loop(Small(sum))
loop(Big n) = if p(n) then n else loop(bigAdd(n,1))

Introduce a new name:

loop_small(n) = if p(n) then n else let sum = n.val+1 in if overflow
then loop(add(Big(n.val),1)) else loop(Small(sum))
loop(Small n) = loop_small(n)
loop(Big n) = if p(n) then n else loop(bigAdd(n,1))

Inline loop into loop_small and eliminate dead code, turning
loop(Small(sum)) into loop_small(Small(sum)):

loop_small(n) = if p(n) then n else let sum = n.val+1 in if overflow
then loop(add(Big(n.val),1)) else loop_small(Small(sum))
loop(Small n) = loop_small(n)
loop(Big n) = if p(n) then n else loop(bigAdd(n,1))

Note that we have eliminated the checks (in this case pattern
matching) from the loop_small loop! Inlining + dead code elimination
did the trick. Sure, we are still using a boxed representation in
loop_small, but it's not polymorphic anymore and standard algorithms
can turn the heap allocated Small instances into stack allocated local
int variables (essentially inlining the Small class' instance
variables into the local variables, in this case only val).

It's not trivial to build a compiler that does this, but it's not
impossible either. Perhaps the JVM already does some of this. You can
get best of both worlds: speed *and* correctness. The situation is not
pick one: speed, correctness, it is pick two: speed, correctness,
simple compiler.

Jules

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


Re: Enhanced Primitive Support

2010-06-19 Thread Mark Engelberg
On Sat, Jun 19, 2010 at 12:20 PM, Nicolas Oury nicolas.o...@gmail.com wrote:
 Not ordinary code. 10^19 is big.

Nicolas, I think you misunderstand my point.  I'm talking about
loop/recur behavior.  If you initialize a loop with the literal 1, and
then recur with a number 2 that's pulled from a collection (and thus
boxed), it will break.  That's ordinary code.

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


Re: Enhanced Primitive Support

2010-06-19 Thread Brian Goslinga
On Jun 19, 2:24 pm, Mark Engelberg mark.engelb...@gmail.com wrote:
 On Sat, Jun 19, 2010 at 12:20 PM, Nicolas Oury nicolas.o...@gmail.com wrote:
  Not ordinary code. 10^19 is big.

 Nicolas, I think you misunderstand my point.  I'm talking about
 loop/recur behavior.  If you initialize a loop with the literal 1, and
 then recur with a number 2 that's pulled from a collection (and thus
 boxed), it will break.  That's ordinary code.
What if loop had its current functionality, but if one tries to recur
with a different type, the affected loop variable becomes
automatically boxed (and if *warn-on-reflection* or a similar variable
is set, the compiler emits an note)?  What would be the downside of
this approach?  All of the code that currently works correctly with
the current state of the equal branch remains fast, and all of these
examples of bad behaviour should just work, and the programmer should
be able to ask to know about them.

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


Re: Enhanced Primitive Support

2010-06-19 Thread Mike Meyer
On Sat, 19 Jun 2010 11:00:39 +0100
Nicolas Oury nicolas.o...@gmail.com wrote:
  There is a bit of arithmetic involved everywhere, and around 2-3 double
 operations per function in the part choosing the instance of rule to apply.

That still sounds arithmetic-heavy to me. In looking through my code,
I find three different classes of algorithm:

1) Things that are hard-core number-crunching, which for me is usually
   either combinatorics or crypto, where bigint is either a necessity
   or a major convenience.

2) Searches of various kinds, where most of the code manipulates
   trees/graphs to be searched with no (explicit) arithmetic, and one
   function evaluates a node with maybe a half-dozen arithmetic ops,
   meaning an average of 1 arithmetic op per function.

3) Everything else (web hacks, database stuff, string processing,
   etc.) where there's basically *no* arithmetic.

I guess the real question I should be asking is:

Where can I get jar files of the various branches so I can test for
myself without having to deploy whatever infrastructure is needed to
build clojure these days? Or am I likely to be able to build them with
tools found in the BSD ports tree?

  mike
-- 
Mike Meyer m...@mired.org http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.

O ascii ribbon campaign - stop html mail - www.asciiribbon.org

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


Re: Enhanced Primitive Support

2010-06-19 Thread Mike Meyer
On Sat, 19 Jun 2010 10:43:36 -0400
David Nolen dnolen.li...@gmail.com wrote:

 On Sat, Jun 19, 2010 at 5:13 AM, Mike Meyer 
 mwm-keyword-googlegroups.620...@mired.org wrote:
 
 
  Were those real world programs, or arithmetic benchmarks? Most real world
  programs I see spend so little of their time doing arithmetic that making
  the math an order of magnitude slower wouldn't make a noticeable difference
  in overall runtime.
 
 
 Most real world programs. You mean like Clojure itself?
 
 Please look over the implementation of gvec before making statements like
 this:

This is actually the what I'm trying to figure out. While *my* code
may have no explicit arithmetic in it, it's not clear without diving
into the guts of clojure how much arithmetic gets done in it's name by
things like gvec.

   mike
-- 
Mike Meyer m...@mired.org http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.

O ascii ribbon campaign - stop html mail - www.asciiribbon.org

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


Re: Enhanced Primitive Support

2010-06-19 Thread Mike Meyer
While I generally favor correct over fast (worrying about fast before
you're correct is a good sign that you're engaged in premature
optimization), I'm still trying to figure out the tradeoffs
here. Especially since most LISPs  other dynamic languages don't seem
to run into this issue - or at least the debate that we're seeing
here.

IIUC, the problem is that we've got three kinds (not types; which
normally refers to bit lengths) of integer:

primitive, which is what the JVM does it's math with.
boxed, which is the primitive wrapped in a Java object, and what Java
   normally uses.
bigint, which is a clojure-specific kind of integer.

Other numeric types don't have issues because they don't have all
three kinds (is that right? Or could this entire thread be rewritten
in terms of primitive vs. boxed floats?).

And the bottom line is that for some reason we can't get from
primitives (which are required for speed) to bigints (which are
required to maximize the domain for which we get correct answers)
automatically. 

Assuming that that's right, the first question that occurs to me is:
Does clojure really need java's boxed types? Other than for java
interop, of course. 

Again, other languages seem to get by with the platform primitives
(module tweaks to get type information) going to bigints, and to get
reasonable performance by throwing away the dynamic nature of the
language for the hot spots. Could clojure do something similar, or is
this something technical issue with the JVM, similar to the reason we
don't get TCE?

  mike
-- 
Mike Meyer m...@mired.org http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.

O ascii ribbon campaign - stop html mail - www.asciiribbon.org

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


Re: Enhanced Primitive Support

2010-06-19 Thread Mike Meyer
On Sat, 19 Jun 2010 20:20:48 +0100
Nicolas Oury nicolas.o...@gmail.com wrote:

 Not ordinary code. 10^19 is big.

No, Aleph-2 is big. Any non-infinite number you can name in your
lifetime is small ;-).

Pretty much any time I really need integer speed, I also deal with
numbers that can get much larger than 10^19th, because I tend to be
doing combinatorics or cryptography.

True, this represents a small fraction of all programs. The question
I'd really like answered is how much difference does this make for
non-numeric clojure code, where only a few percent of the calls to
core functions are calls to integer ops.

 mike
-- 
Mike Meyer m...@mired.org http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.

O ascii ribbon campaign - stop html mail - www.asciiribbon.org

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


Re: Enhanced Primitive Support

2010-06-19 Thread Nicolas Oury
On Sat, Jun 19, 2010 at 10:15 PM, Mike Meyer m...@mired.org wrote:



 Pretty much any time I really need integer speed, I also deal with
 numbers that can get much larger than 10^19th, because I tend to be
 doing combinatorics or cryptography.

 But you would agree that for this kind of domain, it wouldn't be too bad to
be explicit about
wanting bigint. If you write a program that work with XML, you don't ask
clojure data to be
encoded in XML.



 True, this represents a small fraction of all programs. The question
 I'd really like answered is how much difference does this make for
 non-numeric clojure code, where only a few percent of the calls to
 core functions are calls to integer ops.


I tried on some code with 1/2 ops per functions and already quite a dew
annotations. 10% speed-up in a program that spend 80% in Object.hashCode
(which does not get accelerated at all).
I think that's due to the 1/2 ops + the ops hidden in clojure library code.
I'd like to see more results like that and bugs in real programs.
It was a matter of minutes to try.
- pull the branch with git
- compile with ant
- replace your clojure.jar
- recompile.

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

Re: Enhanced Primitive Support

2010-06-19 Thread Michał Marczyk
On 19 June 2010 16:43, David Nolen dnolen.li...@gmail.com wrote:
 Most real world programs. You mean like Clojure itself?
 Please look over the implementation of gvec before making statements like
 this:

Surely Clojure's internals are a *very* special case though... I
wouldn't find it particularly worrying if they turned out to require
some hinting.

I suppose even Ruby 1.8 must have its fair share of full-speed C math
under the hood (disclaimer: I'm not a Rubyist though, so I never cared
to check), which has nothing to do with the performance of math in
user programmes, which is what I interpreted Mike's statement to be
referring to.

Sincerely,
Michał

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


Re: Enhanced Primitive Support

2010-06-19 Thread Michał Marczyk
On 19 June 2010 23:51, Mike Meyer
mwm-keyword-googlegroups.620...@mired.org wrote:
 In any case, I don't think 10% is enough gain to justify narrowing the
 range for which naive programs are correct. An order of magnitude
 would be. A factor of two is a maybe.

QFT!

Have a look at this:

(defn fact [n]
  (loop [n n r 1]
(if (zero? n)
  r
  (recur (dec n) (* r n)

This doesn't compile. To make it compile, the initial value of r has
to be given as (num 1) *or* the initial binding of the inner n has
to be given as (long n). Changing the ops to *' and dec' rules out the
latter option, but the (num ...) hint on r is still required. Not
surprisingly having r start off with (Long. 1) solves makes this
compile too.

The summary is that I'm finding it impossible to write a standard
tail-recursive factorial function without type hints on my literals. I
suppose I can guess what the reason is by now, but I find it
unreasonably confusing. Not sure to which degree this can be ironed
out if boxing were to remain an opt-in rather than -out...?

Oh, just in case votes on this are of interest, I like the idea of
loop' for fast-by-default looping.

Sincerely,
Michał

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


Re: Enhanced Primitive Support

2010-06-19 Thread Mark Engelberg
On Sat, Jun 19, 2010 at 4:10 PM, Michał Marczyk
michal.marc...@gmail.com wrote:
 (defn fact [n]
  (loop [n n r 1]
    (if (zero? n)
      r
      (recur (dec n) (* r n)

Thanks for posting this surprisingly simple example of something that
looks like it should work, but wouldn't under the current proposal.
Really demonstrates how even for straightforward programs you would
have to do a certain amount of type flow analysis to verify that it
will compile.

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


Re: Enhanced Primitive Support

2010-06-19 Thread David Nolen
On Sat, Jun 19, 2010 at 4:10 PM, Michał Marczyk
michal.marc...@gmail.com wrote:
 (defn fact [n]
  (loop [n n r 1]
(if (zero? n)
  r
  (recur (dec n) (* r n)

Huh? That doesn't look like it's going to work at all.

1) 1 is primitive, we know that, accept it
2) we don't know the type of n, what will (* r n) be?
3) BOOM!

My suggestion is to stop it with the contrived examples. Start showing some
real code, real problems in your real programs. Using loop/recur is already
the beginning of code smell for anything that is not performance sensitive.

(defn fact
  ([n] (fact n 1))
  ([n r] (if (zero? n)
  r
  (recur (dec n) (* r n)

Sleep soundly.

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

Re: Enhanced Primitive Support

2010-06-19 Thread Peter Schuller
 Where can I get jar files of the various branches so I can test for
 myself without having to deploy whatever infrastructure is needed to
 build clojure these days? Or am I likely to be able to build them with
 tools found in the BSD ports tree?

It still seems to build with 'ant' like it always has for me? Install
devel/apache-ant and simply run 'ant' in the clojure checkout.

If you want to get the maven artifact installed in your local
repository for use with leiningen/maven projects, you first want to
install devel/maven2. The complication is that clojure is not built by
maven (normally you would just 'mvn install'), but instead is built
with Ant with it's maven tasks. So, you need to drop in:

   http://www.apache.org/dyn/closer.cgi/maven/binaries/maven-ant-tasks-2.1.0.jar

Into ~/.ant/lib so that ant can pick that up. Afterwards, you should
be able to run:

  ant ci-build

And that should install (although it does so very silently) clojure
into your (user) local maven repository:

  ls -ltr ~/.m2/repository/org/clojure/clojure/1.2.0-master-SNAPSHOT

-- 
/ Peter Schuller

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


Re: Enhanced Primitive Support

2010-06-19 Thread Mark Engelberg
On Sat, Jun 19, 2010 at 5:13 PM, David Nolen dnolen.li...@gmail.com wrote:
 Huh? That doesn't look like it's going to work at all.
 1) 1 is primitive, we know that, accept it
 2) we don't know the type of n, what will (* r n) be?
 3) BOOM!

Yes David, if you have a deep understanding of how loop/recur
interacts with primitives, and you understand that n, as an input is
boxed and that literals are primitives, it is of course possible to do
the analysis and see why it doesn't work.

But it does look like it *should* work -- in current Clojure it works,
and the same kind of code in just about any dynamically typed language
I can think of would work.  It might not work in a statically typed
language, but the types would be right there in your face, so it would
be totally obvious what was going on.  The problem is that the
behavior is dependent on something that is invisible from the code,
and requires considerable reasoning even for this simple example.

 My suggestion is to stop it with the contrived examples. Start showing some
 real code, real problems in your real programs. Using loop/recur is already
 the beginning of code smell for anything that is not performance sensitive.

I think the notion that loop/recur is a code smell for anything that
isn't performance sensitive is absurd.  It's basically the only
looping mechanism that Clojure offers - it's in all types of code.

 (defn fact
   ([n] (fact n 1))
   ([n r] (if (zero? n)
           r
           (recur (dec n) (* r n)
 Sleep soundly.

The fact that this refactoring of the fact function fixes the problem
further bolsters our argument that the newly proposed semantics are
significantly more inscrutable than they should be.  Without a fair
amount of thought, it's completely unobvious why this refactoring
should fix the problem.  (Yes, I know it's because it boxes the 1 when
it passes it to the two-arg version, but stuff like this really
shouldn't make such a significant difference in behavior).

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


Re: Enhanced Primitive Support

2010-06-19 Thread Mike Meyer
On Sat, 19 Jun 2010 20:13:07 -0400
David Nolen dnolen.li...@gmail.com wrote:

 On Sat, Jun 19, 2010 at 4:10 PM, Michał Marczyk
 michal.marc...@gmail.com wrote:
  (defn fact [n]
   (loop [n n r 1]
 (if (zero? n)
   r
   (recur (dec n) (* r n)
 
 Huh? That doesn't look like it's going to work at all.
 
 1) 1 is primitive, we know that, accept it
 2) we don't know the type of n, what will (* r n) be?
 3) BOOM!
 
 My suggestion is to stop it with the contrived examples. Start showing some
 real code, real problems in your real programs. Using loop/recur is already
 the beginning of code smell for anything that is not performance sensitive.

Oh, come on. I didn't write that example, but it's a perfect
reasonable implementation of the factorial loop algorithm.

I'd say that you're calling using loop/recur a code smell is itself
a smell, indicating that loop/recur is broken.

   mike
-- 
Mike Meyer m...@mired.org http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.

O ascii ribbon campaign - stop html mail - www.asciiribbon.org

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


Re: Enhanced Primitive Support

2010-06-19 Thread Rob Lachlan
The main example for recur on the special forms page (http://
clojure.org/special_forms#Special%20Forms--(recur%20exprs*)) is:

(def factorial
  (fn [n]
(loop [cnt n acc 1]
   (if (zero? cnt)
acc
  (recur (dec cnt) (* acc cnt))

I may not be be clojure jedi, but I've been learning the language for
a while.  I've never come across the notion that this is a code
smell.  I thought that the loop recur form was perfectly orthodox.

Also, the fact that the form above doesn't compile in the equal branch
does make me a little uneasy.

Rob

On Jun 19, 5:13 pm, David Nolen dnolen.li...@gmail.com wrote:
 On Sat, Jun 19, 2010 at 4:10 PM, Michał Marczyk

 michal.marc...@gmail.com wrote:
  (defn fact [n]
   (loop [n n r 1]
     (if (zero? n)
       r
       (recur (dec n) (* r n)

 Huh? That doesn't look like it's going to work at all.

 1) 1 is primitive, we know that, accept it
 2) we don't know the type of n, what will (* r n) be?
 3) BOOM!

 My suggestion is to stop it with the contrived examples. Start showing some
 real code, real problems in your real programs. Using loop/recur is already
 the beginning of code smell for anything that is not performance sensitive.

 (defn fact
   ([n] (fact n 1))
   ([n r] (if (zero? n)
           r
           (recur (dec n) (* r n)

 Sleep soundly.

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


Re: Enhanced Primitive Support

2010-06-19 Thread David Nolen
Mark and Mike you fail to address my deeper question. I've been using
many different Clojure libraries all day long with the latest equals
branch. Guess
what?

No loop/recur bugs.

When you guys start postIng your broken code that has this problem
then people can start believing it is an issue for working code.

Until then this is just theoretical rhetoric.

On Saturday, June 19, 2010, Mark Engelberg mark.engelb...@gmail.com wrote:
 On Sat, Jun 19, 2010 at 5:13 PM, David Nolen dnolen.li...@gmail.com wrote:
 Huh? That doesn't look like it's going to work at all.
 1) 1 is primitive, we know that, accept it
 2) we don't know the type of n, what will (* r n) be?
 3) BOOM!

 Yes David, if you have a deep understanding of how loop/recur
 interacts with primitives, and you understand that n, as an input is
 boxed and that literals are primitives, it is of course possible to do
 the analysis and see why it doesn't work.

 But it does look like it *should* work -- in current Clojure it works,
 and the same kind of code in just about any dynamically typed language
 I can think of would work.  It might not work in a statically typed
 language, but the types would be right there in your face, so it would
 be totally obvious what was going on.  The problem is that the
 behavior is dependent on something that is invisible from the code,
 and requires considerable reasoning even for this simple example.

 My suggestion is to stop it with the contrived examples. Start showing some
 real code, real problems in your real programs. Using loop/recur is already
 the beginning of code smell for anything that is not performance sensitive.

 I think the notion that loop/recur is a code smell for anything that
 isn't performance sensitive is absurd.  It's basically the only
 looping mechanism that Clojure offers - it's in all types of code.

 (defn fact
   ([n] (fact n 1))
   ([n r] (if (zero? n)
           r
           (recur (dec n) (* r n)
 Sleep soundly.

 The fact that this refactoring of the fact function fixes the problem
 further bolsters our argument that the newly proposed semantics are
 significantly more inscrutable than they should be.  Without a fair
 amount of thought, it's completely unobvious why this refactoring
 should fix the problem.  (Yes, I know it's because it boxes the 1 when
 it passes it to the two-arg version, but stuff like this really
 shouldn't make such a significant difference in behavior).

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

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


Re: need help understanding two issues

2010-06-19 Thread Michał Marczyk
On 19 June 2010 18:59, Albert Cardona sapri...@gmail.com wrote:
 1. How come APersistentMap$KeySet doesn't implement IPersistentSet?

Beyond what Rob has already written above, keys works with
APersistentMap$KeySeq (note the q at the end), not
APersistentMap$KeySet. To get at the latter, use (.keySet {:a 1 :b
2}); you'll get back a java.util.Set of two entries, :a and :b. This
is mainly an interop feature, I believe (meant to make it easier for
non-Clojure code on the JVM to read Clojure data structures directly).

clojure.set/intersection knows how to handle java.util.Set instances,
though in this case, using (comp set keys) -- that is, normally, (set
(keys ...)) -- is the more usual and overall more sensible way to go.

 2. I can't get clojure.set/project to work.

clojure.set/project is meant to implement the projection operator of
[Relational algebra](http://en.wikipedia.org/wiki/Relational_algebra).

The representation of relations assumed here is a collection of
tuples, which makes sense: the mathematical definition of a relation
-- the one used in relational algebra -- is a set of tuples. The
tuples are here represented as maps. Of course in a mathematical
relation all tuples have the same format; in Clojure, if some of the
maps happen to be missing some of the keys present in some of the
other maps, the overall semantics are very much (if not exactly) as if
they had those keys bound to nil (as the usual Clojure semantics for
maps would imply).

Now the projection operator takes a relation and throws out some of
its attributes (or some of the columns if you visualise it as a table;
or if you think of a set of tuples, it removes some axes from all the
tuples). The result is still a relation, i.e. a set, meaning in
particular that there are no duplicates:

(clojure.set/project #{{:foo 1 :bar 2} {:foo 1 :bar 3}} [:foo])

returns #{{:foo 1}}, because once we throw out the :bars, the two
tuples from the input relation become indistinguishable on the basis
of the remaining :foo attribute and blend together into just one
tuple in the output relation.

An example where the projection is larger:

(clojure.set/project #{{:foo 1 :bar 2} {:foo 2 :quux 3}} [:foo])
; = #{{:foo 1} {:foo 2}}

So, that's how it's supposed to work. Your final example should
perhaps fail more gracefully -- the first argument to
clojure.set/project cannot be a map (which is by definition a
collection of map entries and not of maps, as required here). As
things stand, it gives a weird result due to clojure.set/project using
select-keys, which in turn uses clojure.lang.RT/find, which happens to
return nils when it's called with an argument which makes no sense (in
addition to returning nil when the argument does make sense -- i.e. is
a map -- but the given key is not found).

Sincerely,
Michał

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


Re: Enhanced Primitive Support

2010-06-19 Thread Mike Meyer
On Sat, 19 Jun 2010 20:40:13 -0400
David Nolen dnolen.li...@gmail.com wrote:

 Mark and Mike you fail to address my deeper question.

Maybe because you've failed to ask in your hurry to claim code is
non-idiomatic or calling our example rhetoric.

 I've been using
 many different Clojure libraries all day long with the latest equals
 branch. Guess
 what?
 
 No loop/recur bugs.

I wouldn't expect anything else, for two reasons:

1) Most clojure code doesn't deal with integers - it deals with
   symbols, strings, and sequences. Hence it won't run into this problem.
2) The libraries are generally written by experienced users who will
   have tweaked them for performance - meaning they've typed hinted
   them, and thus avoided this problem.

 When you guys start postIng your broken code that has this problem
 then people can start believing it is an issue for working code.

I guess a perfectly natural expression of a reasonable algorithm that
works under 1.1 and doesn't on the equal branch isn't broken because
it's the same function we've been using all along. So here's some new
examples, pulled in sequence from some of my combinatorics code:

(defn count-in [value col]
   (loop [value value col col res 0]
  (if (empty? col)
  res
  (recur value (rest col) (if (= (first col) value) (inc res) res)

(defn ones-n-zeros [vectors]
  (loop [vectors vectors m-zeros 0 m-ones 0]
 (if (empty? vectors)
 [m-zeros m-ones]
 (let [data (first vectors)
   zeros (count-in 0 data)
   ones (count-in 1 data)]
(recur (rest vectors) (if ( zeros ones) (inc m-zeros) m-zeros)
  (if ( ones zeros) (inc m-ones) m-ones))

No, I haven't verified it fails - I've given up trying to check out
the branch, as hg convert failed, and git (after reinstalling over a
broken version) keeps complaining about warning: remote HEAD refers
to nonexistent ref, unable to checkout. However, my reading of the
proposal is that the inc's here will cause the same problems as the
*'s in the perfectly reasonable factorial example.

Now go ahead and claim that that's not very good code, because an
expert would have type hinted it or written it with map  apply or
some such, or that there's a contrib library somewhere with a faster
implementation of count-in in it. That, after all, is your rhetoric.

But that's my point. I want the *obvious* code to work. I'll worry
about making it fast after I've made it right. If you want a read-only
language that requires an expert to get working code in a reasonable
amount of time, you can always write in Perl or C.

   mike
-- 
Mike Meyer m...@mired.org http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.

O ascii ribbon campaign - stop html mail - www.asciiribbon.org

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


Re: Enhanced Primitive Support

2010-06-19 Thread Michał Marczyk
On 20 June 2010 02:13, David Nolen dnolen.li...@gmail.com wrote:
 On Sat, Jun 19, 2010 at 4:10 PM, Michał Marczyk
 michal.marc...@gmail.com wrote:
 (defn fact [n]
  (loop [n n r 1]
    (if (zero? n)
      r
      (recur (dec n) (* r n)
 Huh? That doesn't look like it's going to work at all.
 1) 1 is primitive, we know that, accept it
 2) we don't know the type of n, what will (* r n) be?
 3) BOOM!

Yes, I know what's going on, after reading through this rather lengthy
thread and participating in / listening in on a number of exchanges on
#clojure. I still find the notion that this code doesn't look like
it's going to work at all to be fairly surprising. (Also, I'd rather
not refactor a private loop so that it becomes exposed to the outside
world (presumably to be instructed to ignore the binary overload), but
that is beside the point. The (num ...) hint is a simple enough
solution, which incidentally I'd be able to live with if things were
not to go the way I prefer.)

I wanted to address the pre-BOOM points above, though:

1) With the other approach being proposed, this would read something
like 1 is primitive in primitive contexts, but will get boxed if used
as an initialiser for an unhinted local. That's rather a significant
improvement over the stylistically matching description of the
1.2-master ( 1.1) state of affairs (which I'll omit from here while
noting that apparently acceptance was pretty low on that). I'm very
happy to see Clojure moving forward w.r.t. the way in which top
numeric performance can be achieved; that leaves plenty of room for
doubting whether it should be the outright default. So, how about we
address this point...?

2) That is in fact precisely the reason why I find it odd to presume
that we know the desired type of r based on the literal alone.

The question I wanted to pose when posting that factorial example was this:

Should basic arithmetic work with no explicit hints / casts / primed
ops / whatever -- or not necessarily?

This seems like a valid question to me. If the answer is not
necessarily, I'll probably be able to get used to the idea; if it is
yes, or at least hopefully, then perhaps there's something left to
tweak / change etc. Note that if there was a way to have
primitive-by-default arithmetic, yet also have naive arithmetic code
work without hinting, this would be orthogonal to the issue of the
choice of default. (In fact, it could affect my personal preference,
or at least the degree to which I care about it.)

Sincerely,
Michał

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


Re: Enhanced Primitive Support

2010-06-19 Thread Rob Lachlan
Actually, Mike, your two functions work just fine.  (Equal branch).
Mind you I checked that out over two hours ago, so this information
might be out of date.

Rob

On Jun 19, 6:59 pm, Mike Meyer mwm-keyword-googlegroups.
620...@mired.org wrote:
 On Sat, 19 Jun 2010 20:40:13 -0400

 David Nolen dnolen.li...@gmail.com wrote:
  Mark and Mike you fail to address my deeper question.

 Maybe because you've failed to ask in your hurry to claim code is
 non-idiomatic or calling our example rhetoric.

  I've been using
  many different Clojure libraries all day long with the latest equals
  branch. Guess
  what?

  No loop/recur bugs.

 I wouldn't expect anything else, for two reasons:

 1) Most clojure code doesn't deal with integers - it deals with
    symbols, strings, and sequences. Hence it won't run into this problem.
 2) The libraries are generally written by experienced users who will
    have tweaked them for performance - meaning they've typed hinted
    them, and thus avoided this problem.

  When you guys start postIng your broken code that has this problem
  then people can start believing it is an issue for working code.

 I guess a perfectly natural expression of a reasonable algorithm that
 works under 1.1 and doesn't on the equal branch isn't broken because
 it's the same function we've been using all along. So here's some new
 examples, pulled in sequence from some of my combinatorics code:

 (defn count-in [value col]
    (loop [value value col col res 0]
       (if (empty? col)
           res
           (recur value (rest col) (if (= (first col) value) (inc res) res)

 (defn ones-n-zeros [vectors]
   (loop [vectors vectors m-zeros 0 m-ones 0]
      (if (empty? vectors)
          [m-zeros m-ones]
          (let [data (first vectors)
                zeros (count-in 0 data)
                ones (count-in 1 data)]
             (recur (rest vectors) (if ( zeros ones) (inc m-zeros) m-zeros)
                                   (if ( ones zeros) (inc m-ones) m-ones))

 No, I haven't verified it fails - I've given up trying to check out
 the branch, as hg convert failed, and git (after reinstalling over a
 broken version) keeps complaining about warning: remote HEAD refers
 to nonexistent ref, unable to checkout. However, my reading of the
 proposal is that the inc's here will cause the same problems as the
 *'s in the perfectly reasonable factorial example.

 Now go ahead and claim that that's not very good code, because an
 expert would have type hinted it or written it with map  apply or
 some such, or that there's a contrib library somewhere with a faster
 implementation of count-in in it. That, after all, is your rhetoric.

 But that's my point. I want the *obvious* code to work. I'll worry
 about making it fast after I've made it right. If you want a read-only
 language that requires an expert to get working code in a reasonable
 amount of time, you can always write in Perl or C.

        mike
 --
 Mike Meyer m...@mired.org          http://www.mired.org/consulting.html
 Independent Network/Unix/Perforce consultant, email for more information.

 O ascii ribbon campaign - stop html mail -www.asciiribbon.org

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


Re: Enhanced Primitive Support

2010-06-19 Thread Michał Marczyk
On 20 June 2010 03:59, Mike Meyer
mwm-keyword-googlegroups.620...@mired.org wrote:
 So here's some new
 examples, pulled in sequence from some of my combinatorics code:

This works fine as far as arithmetic ops are concerned, though I
suppose it might suffer from issues of = vs. == now (which is a
separate matter).

Sincerely,
Michał

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


Re: Enhanced Primitive Support

2010-06-19 Thread Rob Lachlan
I don't think my computer has enough memory to test that.  But, you're
right, I might have spoken hastily.

Rob

On Jun 19, 7:26 pm, Aaron Cohen aa...@assonance.org wrote:
 I actually believe it will throw an overflow exception if col contains
 more than Integer.MAX_VALUE elements. Hard to confirm without getting
 bored though.

 -- Aaron



 On Sat, Jun 19, 2010 at 10:19 PM, Rob Lachlan robertlach...@gmail.com wrote:
  Actually, Mike, your two functions work just fine.  (Equal branch).
  Mind you I checked that out over two hours ago, so this information
  might be out of date.

  Rob

  On Jun 19, 6:59 pm, Mike Meyer mwm-keyword-googlegroups.
  620...@mired.org wrote:
  On Sat, 19 Jun 2010 20:40:13 -0400

  David Nolen dnolen.li...@gmail.com wrote:
   Mark and Mike you fail to address my deeper question.

  Maybe because you've failed to ask in your hurry to claim code is
  non-idiomatic or calling our example rhetoric.

   I've been using
   many different Clojure libraries all day long with the latest equals
   branch. Guess
   what?

   No loop/recur bugs.

  I wouldn't expect anything else, for two reasons:

  1) Most clojure code doesn't deal with integers - it deals with
     symbols, strings, and sequences. Hence it won't run into this problem.
  2) The libraries are generally written by experienced users who will
     have tweaked them for performance - meaning they've typed hinted
     them, and thus avoided this problem.

   When you guys start postIng your broken code that has this problem
   then people can start believing it is an issue for working code.

  I guess a perfectly natural expression of a reasonable algorithm that
  works under 1.1 and doesn't on the equal branch isn't broken because
  it's the same function we've been using all along. So here's some new
  examples, pulled in sequence from some of my combinatorics code:

  (defn count-in [value col]
     (loop [value value col col res 0]
        (if (empty? col)
            res
            (recur value (rest col) (if (= (first col) value) (inc res) 
  res)

  (defn ones-n-zeros [vectors]
    (loop [vectors vectors m-zeros 0 m-ones 0]
       (if (empty? vectors)
           [m-zeros m-ones]
           (let [data (first vectors)
                 zeros (count-in 0 data)
                 ones (count-in 1 data)]
              (recur (rest vectors) (if ( zeros ones) (inc m-zeros) m-zeros)
                                    (if ( ones zeros) (inc m-ones) 
  m-ones))

  No, I haven't verified it fails - I've given up trying to check out
  the branch, as hg convert failed, and git (after reinstalling over a
  broken version) keeps complaining about warning: remote HEAD refers
  to nonexistent ref, unable to checkout. However, my reading of the
  proposal is that the inc's here will cause the same problems as the
  *'s in the perfectly reasonable factorial example.

  Now go ahead and claim that that's not very good code, because an
  expert would have type hinted it or written it with map  apply or
  some such, or that there's a contrib library somewhere with a faster
  implementation of count-in in it. That, after all, is your rhetoric.

  But that's my point. I want the *obvious* code to work. I'll worry
  about making it fast after I've made it right. If you want a read-only
  language that requires an expert to get working code in a reasonable
  amount of time, you can always write in Perl or C.

         mike
  --
  Mike Meyer m...@mired.org          http://www.mired.org/consulting.html
  Independent Network/Unix/Perforce consultant, email for more information.

  O ascii ribbon campaign - stop html mail -www.asciiribbon.org

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

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


Re: How to use Clojure with Robocode

2010-06-19 Thread nakkaya
This answer is couple months too late but I was messing with robocode
this weekend, had the same problem OP had. The solution is to unzip
clojure.jar into the folder where your compiled class files are. That
makes the error go away but it will also increase robocode's boot time
by 20-30 secs.

Hope this helps...
--
Nurullah Akkaya
http://nakkaya.com

On Mar 19, 10:56 am, ubolonton ubolon...@gmail.com wrote:
 Hi,

 Has anyone been able to use Clojure with Robocode?
 I've followed thishttp://www.fatvat.co.uk/2009/05/clojure-and-robocode.html
 but got the error

 Round 1 initializing..
 Let the games begin!
 java.lang.ExceptionInInitializerError
         at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native
 Method)
         at
 sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAcce 
 ssorImpl.java:
 39)
         at
 sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstru 
 ctorAccessorImpl.java:
 27)
         at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
         at java.lang.Class.newInstance0(Class.java:355)
         at java.lang.Class.newInstance(Class.java:308)
         at
 net.sf.robocode.host.security.RobotClassLoader.createRobotInstance(RobotCla 
 ssLoader.java:
 272)
         at
 net.sf.robocode.host.proxies.HostingRobotProxy.loadRobotRound(HostingRobotP 
 roxy.java:
 201)
         at
 net.sf.robocode.host.proxies.HostingRobotProxy.run(HostingRobotProxy.java:
 242)
         at java.lang.Thread.run(Thread.java:637)
 Caused by: java.lang.NullPointerException
         at clojure.lang.Var.setMeta(Var.java:179)
         at clojure.lang.Var.internPrivate(Var.java:96)
         at ubolonton.MyRobot.clinit(Unknown Source)
         ... 10 more

 Thanks

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


Re: Enhanced Primitive Support

2010-06-19 Thread Mike Meyer

Rob Lachlan robertlach...@gmail.com wrote:

Actually, Mike, your two functions work just fine.  (Equal branch).
Mind you I checked that out over two hours ago, so this information
might be out of date.

Rob

On Jun 19, 6:59 pm, Mike Meyer mwm-keyword-googlegroups.

Ok, why does this work but the fact fail? Or does the fact example still fail 
on that build?

The fact that this requires explanation is a pretty good argument the fact 
behavior.


 (defn count-in [value col]
    (loop [value value col col res 0]
       (if (empty? col)
           res
           (recur value (rest col) (if (= (first col) value) (inc res) 
 res)

 (defn ones-n-zeros [vectors]
   (loop [vectors vectors m-zeros 0 m-ones 0]
      (if (empty? vectors)
          [m-zeros m-ones]
          (let [data (first vectors)
                zeros (count-in 0 data)
                ones (count-in 1 data)]
             (recur (rest vectors) (if ( zeros ones) (inc m-zeros) m-zeros)
                                   (if ( ones zeros) (inc m-ones) 
 m-ones))

-- 
Sent from my Android phone with K-9 Mail. Please excuse my brevity.

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


Re: Enhanced Primitive Support

2010-06-19 Thread Rob Lachlan
Because the compiler is upset that it doesn't know what n is.  r is a
long, but n is ???.  The following works:

(defn ^:static fact [^long n]
  (loop [n n r 1]
(if (zero? n)
  r
  (recur (dec n) (* r n)

Or see Dnolen's version above.  But yeah, I wish that it still worked,
because it used to work just fine.

Rob

On Jun 19, 8:22 pm, Mike Meyer mwm-keyword-googlegroups.
620...@mired.org wrote:
 Rob Lachlan robertlach...@gmail.com wrote:
 Actually, Mike, your two functions work just fine.  (Equal branch).
 Mind you I checked that out over two hours ago, so this information
 might be out of date.

 Rob

 On Jun 19, 6:59 pm, Mike Meyer mwm-keyword-googlegroups.

 Ok, why does this work but the fact fail? Or does the fact example still fail 
 on that build?

 The fact that this requires explanation is a pretty good argument the fact 
 behavior.

  (defn count-in [value col]
     (loop [value value col col res 0]
        (if (empty? col)
            res
            (recur value (rest col) (if (= (first col) value) (inc res) 
  res)

  (defn ones-n-zeros [vectors]
    (loop [vectors vectors m-zeros 0 m-ones 0]
       (if (empty? vectors)
           [m-zeros m-ones]
           (let [data (first vectors)
                 zeros (count-in 0 data)
                 ones (count-in 1 data)]
              (recur (rest vectors) (if ( zeros ones) (inc m-zeros) m-zeros)
                                    (if ( ones zeros) (inc m-ones) 
  m-ones))

 --
 Sent from my Android phone with K-9 Mail. Please excuse my brevity.

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


Re: Enhanced Primitive Support

2010-06-19 Thread Mike Meyer

Rob Lachlan robertlach...@gmail.com wrote:

Because the compiler is upset that it doesn't know what n is.  r is a
long, but n is ???.  The following works:

(defn ^:static fact [^long n]
  (loop [n n r 1]
(if (zero? n)
  r
  (recur (dec n) (* r n)

Or see Dnolen's version above.  But yeah, I wish that it still worked,
because it used to work just fine.

Is there reason the compiler can't box r instead of throwing an exception?
-- 
Sent from my Android phone with K-9 Mail. Please excuse my brevity.

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


Re: Enhanced Primitive Support

2010-06-19 Thread Aaron Cohen
On Sat, Jun 19, 2010 at 11:22 PM, Mike Meyer
mwm-keyword-googlegroups.620...@mired.org wrote:

 Rob Lachlan robertlach...@gmail.com wrote:

Actually, Mike, your two functions work just fine.  (Equal branch).
Mind you I checked that out over two hours ago, so this information
might be out of date.

Rob

On Jun 19, 6:59 pm, Mike Meyer mwm-keyword-googlegroups.

 Ok, why does this work but the fact fail? Or does the fact example still fail 
 on that build?

 The fact that this requires explanation is a pretty good argument the fact 
 behavior.


 (defn fact [n]
  (loop [n n r 1]
   (if (zero? n)
 r
 (recur (dec n) (* r n)


(The quoting in this thread is getting out-of-hand, everyone please
reply on the bottom)

The difference between your examples and the fact examples is that

(inc prim) - prim

while

(* prim boxed) - boxed

In the fact example, the type of n as an initializer in the loop
statement is unknown at compile time and thus must be boxed. The fact
that you need to know that, is very much what some people are arguing
against.

The choices are to do either:

(loop [n n r (num 1)]

or

(loop [n (long n) r 1]

Either option will make (* r n) return a primitive or boxed value of
the appropriate type. Both versions will overflow and throw an
exception at (fact 21).

To have a fact that works for large numbers you need:

(defn fact [n]
 (loop [n n r (num 1)]
   (if-not (pos? n)
 r
 (recur (dec n) (*' r n)

Most of the versions posted so far were broken for negative n by the way.

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