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.