Thanks Tassilo, Jeroen, Gary.  I have to think about those suggestions and 
investigate, but I wanted to quickly specify the error in response to 
Gary's question.  If, in project.clj, I specify:

:aot [students.AltState students.Student students.Students 
students.TemperingSteppable students.StudentsWithUI]

(note Student is before Students) I get:

java.lang.ClassNotFoundException: students.Students, 
compiling:(students/Student.clj:45:1)

Line 45 is is the step defn line.  If I put Students before Student in 
project.clj, I get:

java.lang.ClassNotFoundException: students.Student, 
compiling:(Students.clj:59:59)

Line 59 is where I call (Student.) to create a number of Student instances.

The type hint is fully qualified, and it doesn't matter whether call to 
Student. to create instances is fully qualified, or abbreviated after 
import -ing the Student class in the ns statement.

Thanks everyone!  I'll give further details and responses later.  If 
anyone's interested, the code is here:

https://github.com/mars0i/majure/tree/master/3opt2

An unoptimized version is here:

https://github.com/mars0i/majure/tree/master/3plus

And the Java version on which its based is here:

https://github.com/mars0i/majure/tree/master/0plus



On Tuesday, May 19, 2015 at 4:21:52 AM UTC-5, Gary Verhaegen wrote:
>
> I do not understand the problem. Could you elaborate a bit? Maybe provide 
> a minimal-ish project that reproduces the error?
>
> In particular:
>
> * dependencies between types are easily solved in Java by introducing 
> interfaces as an indirection layer for the type system, or with protocols 
> in Clojure. As your explanations seem to imply that there are 
> already interfaces in your example, I am a bit confused.
> * I was under the impression that Clojure only restricted cyclic 
> dependencies between ns forms. Have you tried calling 
> import/require/gen-class directly?
> * what error do you see? Is the type hint itself refused because Clojure 
> cannot resolve it? Is that still the case if you fully qualify your type 
> hint? Do you have more of a speedup if you hint with the concrete, 
> gen-classed class than with the interface it implements?
>
> I'm inclined to fully agree with you that mutual dependencies between 
> types should be supported, but I do not really see how they are not.
>
> On Tuesday, 19 May 2015, Mars0i <mars...@logical.net <javascript:>> wrote:
>
>> Sorry for the length of this post--I feel I have to spell out the details 
>> in order to head off irrelevant responses.  I'm saving you the trouble of 
>> reading a long chain posts just focused on misunderstandings.
>>
>> For anything below, I'd be happy to find out that I'm wrong, confused, 
>> misguided, etc.
>>
>> I've started using MASON, a library for agent-based models (ABMs) written 
>> in Java.  Using gen-class to follow the MASON model works pretty well, even 
>> if the result is somewhat "Java-esque" Clojure.
>>
>> Using MASON in the normal way involves cyclic dependencies.  This is no 
>> problem if I let Clojure figure out the types at runtime--but I can get a 
>> speed improvement of 11 times the original speed if I add type hints, after 
>> a bit of code reorganization to avoid almost all of the cyclic type 
>> dependencies.  And by adding one additional type hint--more on this 
>> below--I get a further 6.5X speed improvement, for a total improvement due 
>> to type hints of roughly 70X.  Note that speed often matters for ABMs that 
>> involve stochastic effects; it's typically necessary to run the same 
>> simulation many times, and it's useful to be able to do the needed runs in 
>> minutes or hours rather than days.
>>
>> However, the last type hint involves a cyclic type dependency.  It 
>> doesn't generate a cyclic dependency error, but gives class not found 
>> errors no matter which of two interdependent classes is compiled first. My 
>> solution is to delete the type hint, compile all of the Clojure files, add 
>> the type hint back, and recompile that one modified file. That's how I get 
>> the full 85X speed improvement.  (*That* is an ugly solution.)
>>
>> The cyclic dependencies are due to decisions by MASON's designers that 
>> seem entirely reasonable for an agent-based modeling framework--even if I 
>> would do things differently--and *have* done things differently (in a 
>> narrowly-focused, application-specific ABM framework that's purely 
>> functional except for reporting).
>>
>> ******
>>
>> So: In order to use a well-designed Java library, I have to choose 
>> between slow code or awkward workarounds for a cyclic dependency.
>>
>> ******
>>
>> Let me emphasize that I *do not* think that Clojure should incorporate 
>> every feature that someone thinks useful.  I certainly don't think that 
>> Clojure should provide every feature offered by Java.  Ugh.  I love Clojure 
>> because it doesn't include everything plus the kitchen sink, but instead 
>> provides a small set of flexible, simple, well-thought out functions.
>>
>> However, the lack of cyclic dependencies is not the absence of a 
>> substantial language feature.  It's an arbitrary limitation placed on 
>> compile time that's not present at run time.  Allowing cyclic dependencies 
>> wouldn't make Clojure less simple or elegant, because it wouldn't really 
>> add anything to the language.
>>
>> (Yes, if cyclic dependencies are allowed, then people can abuse them. 
>> People can also abuse type hints, interwoven side effects and laziness, 
>> macros, and non-idiomatic coding styles.  The Clojure community teaches 
>> routinely teaches novices how to avoid these mistakes.)
>>
>> (If cyclic dependencies are really considered so harmful, one could hide 
>> them behind a special compiler option that emits a warning when used.)
>>
>> ---------------------------
>>
>> Optional reading: Why there's a cyclic dependency in MASON simulations.
>>
>> MASON simulations typically consist of 
>>
>> (a) One or more "agents", which implement an interface (Steppable) with a 
>> single method, step().
>>
>> (b) An instance of a class that extends SimState, which contains a 
>> scheduler that repeatedly calls step() in every agent that's registered 
>> with it.
>>
>> The agents have to interact with each other, and the way that they find 
>> out about each others' states is typically through the the SimState object 
>> that's automatically passed to step().  The point is that the only way for 
>> teach Student to know about other instances of Students is by knowing about 
>> an object that also has to know about Students. There's the cycle.  (An 
>> alternative might be to have each Student maintain a collection of all 
>> other Students, but that's ugly and unnecessary.)
>>
>> I use gen-class in order to implement Steppable and to extend SimState. 
>> The type hint that I delete and restore is for the second argument to the 
>> step() function required by Steppable:
>>
>> (defn -step [^students.Student this ^students.StudentsSimState sim-state]
>>
>> -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>

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

Reply via email to