This should probably be an FAQ: toplevels do not remember include-paths
of libraries linked with them. This means that you have to explicitly
tell your toplevel where to find the module interfaces (.cmi-files), e.g.:
ocamlunx -I +camlp4 -I +contrib
Only then can you reference modules in those libraries. Maybe this should
be mentioned in chapter 9.5 of the manual?
Regards,
Markus Mottl
--
Markus Mottl mar...@oefai.at
Austrian Research Institute
for Artificial Intelligence http://www.oefai.at/~markus
-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-lis...@inria.fr Archives: http://caml.inria.fr
On Mon, Jan 21, 2002 at 11:43:36PM +0100, Markus Mottl wrote:
> This should probably be an FAQ: toplevels do not remember include-paths
> of libraries linked with them. This means that you have to explicitly
> tell your toplevel where to find the module interfaces (.cmi-files), e.g.:
>
> ocamlunx -I +camlp4 -I +contrib
You can create a file, "foo.ml" holding:
Topdirs.dir_directory "+contrib";;
compile it and add "foo.cmo" in your ocamlmktop command line. For Camlp4,
it is not necessary, because it has beeen already added in the toplevel
directory path in OCaml version 3.04.
--
Daniel de RAUGLAUDRE
daniel.de_...@inria.fr
http://cristal.inria.fr/~ddr/
> This should probably be an FAQ: toplevels do not remember
> include-paths
> of libraries linked with them. This means that you have to explicitly
> tell your toplevel where to find the module interfaces (.cmi-files),
> e.g.:
>
> ocamlunx -I +camlp4 -I +contrib
Thanks a lot for the support.
>
> Only then can you reference modules in those libraries. Maybe this
> should
> be mentioned in chapter 9.5 of the manual?
I think that it's important to mention it at least as a "gotcha" as you told.
But I consider it as a bug, I mean you already mentioned the "-I +contrib"
operation when you create the toplevel with ocamlmktop.
And you don't want to mention this option each time you want to test
something.
Regards,
--
Christian Gillot <cgi...@gruposbd.com>
GNU/Linux developer
Thanks for this trick! Maybe it should be also mentioned in the docs?
Regards,
Markus Mottl
--
Markus Mottl mar...@oefai.at
Austrian Research Institute
for Artificial Intelligence http://www.oefai.at/~markus
Check the archive. This has been discussed before. I think I even posted a patch.
Chris
(I am also reminded, having seen another email by Chris Hecker, that he
mentioned something along these lines at his talk at the last Game
Developers Conference.)
I am once again learning good 'ol ML language from college days, and
thought it might prove an interesting way to implement a game idea I
have (my idea requires little to no graphics, but IIRC there is a
ocaml-GL binding somehere).
________________________________________________
NOTE: My email address has changed! Please delete any old email
addresses you have and use only the address shown below.
Matthew D Moss
mo...@usermail.com
> I am once again learning good 'ol ML language from college days, and
> thought it might prove an interesting way to implement a game idea I
> have (my idea requires little to no graphics, but IIRC there is a
> ocaml-GL binding somehere).
On a similar note -- is there a tutorial on learning OpenGL with ocaml
(or even just on lablGL in specific) anywhere?
wb
--
Will Benton | "Nicht wie die Welt ist, ist das Mystische,
wi...@acm.org | sondern daß sie ist." --L. Wittgenstein
**GnuPG public key: http://www.cs.wisc.edu/~willb/pubkey
Not sure if this is the kind of game you're thinking about, but I
wrote a couple of card games to teach myself labltk. (I've since
switched to lablgtk for most things, but it seemed more accessible at
the time.) One is a blackjack program that's pretty usable; the other
is a set of programs for one small aspect of poker (identifying best
hands in Hold'Em and Omaha). Let me know off-list if you want the
code, or more info.
--
Eric C. Cooper e c c @ c m u . e d u
Well, one of my big projects (which I postpone ever further ..) is a
chess problem solver/tester. I think ML will prove ideal for that.
Probably not what you wanted, but anyway.
But first I have to finish this hack ... :-)
--
Ian Zimmerman, Oakland, California, U.S.A.
GPG: 433BA087 9C0F 194F 203A 63F7 B1B8 6E5A 8CA3 27DB 433B A087
In his own soul a man bears the source
from which he draws all his sorrows and his joys.
Sophocles.
It makes use of labltk, mostly through the canvas widget. And it works
on Windows and Unix.
I'd be very welcome to contributions, by the way, especially to anyone
who wants to code a 4th-order runge-kutta approximation.
y
--
|--------/ Yaron M. Minsky \--------|
|--------\ http://www.cs.cornell.edu/home/yminsky/ /--------|
Open PGP --- KeyID B1FFD916 (new key as of Dec 4th)
Fingerprint: 5BF6 83E1 0CE3 1043 95D8 F8D5 9F12 B3A9 B1FF D916
I'm writing a commercial game in Ocaml right now (and for the past year, and for the next year ;). I'm reserving judgement on the overall worthiness of Ocaml for games until I actually finish and ship a robust product, but it's been fun and educational at least.
Some short thoughts:
- Performance seems to be totally acceptable so far, but I haven't been focusing on optimization yet, and the options are limited for optimizations-in-the-small short of dropping to C or modifying the compiler, so I'm slightly worried about it in the future. The GC performance predicability and smoothness is a huge looming shadow on the horizon that may or may not materialize, I have no idea.
- Lack of a debugger for native code sucks (not helped by the lack of the bytecode debugger on non-cygwin Win32 builds, and the debugger's not great even when it works after rebuilding for cygwin, in my experience so far).
- The toplevel has been a win (sometimes just as a pseudo-debugger).
- Linking of bytecode and native code would be good. Currently if you're using bytecode (debugging, compile speed, toplevel, etc.) and you need to optimize something, dropping to C is your only choice, which is silly.
- Lack of overloaded operators (needing op. for floats), overloaded functions (need mult_matrix_vector, mult_matrix_matrix, mult_scalar_vector, etc.), and "let mutable" makes imperative mathematical code (most of what I've done so far, since the game uses a lot of physics simulation) messy and overly verbose.
- Closures are great. Variants are great. Pattern matching is good. Code is easier and faster to refactor than in C. I've noticed that code seems to get smaller as I add more features, which is fun and non-intuitive. ;)
- Rigid for-loop structure is lame, recursive functions not as readable (and floats are boxed across them).
- The library has been useful, although it desperately needs an orthogonality pass.
- Labltk was fine for prototyping, but I now have my own Win32 thing I wrote because TK's a pig and unstable. LablGL is working fine but I expect to write a thinner layer over OpenGL/D3D before shipping.
I've got a much bigger list that I'll post at some point. Overall, I don't regret deciding to use Ocaml.
>(I am also reminded, having seen another email by Chris Hecker, that he mentioned something along these lines at his talk at the last Game Developers Conference.)
My talk was about programming language features that C/C++/Java/C# don't have but that seem useful, not about Ocaml specifically.
Have you looked at the hump?
http://caml.inria.fr/hump.html#Games
Also, I found a link a while ago for a small doom-like game written in
Ocaml with openGL which looked kinda neat:
http://www.stanford.edu/~rbridson/spiff.shtml
cheers,
doug
I have a sample gl + gtk little program, which is supposed to become a
landscape editor, but in its very early state. It could serve you very well, i
think, as an example at least. I could send it to you if you are interrested,
please ask me. It is GPLed code though (but copyrighted by me only, so other
arrangements could be made).
Friendly,
Sven Luther
Sorry, I wasn't trying to criticize you, just pointing out that there was an archive in case you didn't know. :)
Chris
A few years ago, François Pessaux wrote two impressive 3D rendering
engines (of the kind found in first-person shooter games) in OCaml:
http://guinness.cs.stevens-tech.edu/~fpessaux/
The first one (OCamlDoom) is entirely software-based and renders
"2.5D" scenes as found in Doom. The second one (OCamlQuake) is full
3D and exploits hardware acceleration via the Glide library. Both
deliver very decent frame rates.
- Xavier Leroy
-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.f=
r/FAQ/
To unsubscribe, mail caml-lis...@inria.fr Archives: http://caml.in=
ria.fr
Thanks for the short list. :) This is the kind of information I was
hoping to hear about, although thanks to all for the samples (and the
kind pointer to the Hump, which I now know about).
>> (I am also reminded, having seen another email by Chris Hecker, that
>> he mentioned something along these lines at his talk at the last Game
>> Developers Conference.)
>
> My talk was about programming language features that C/C++/Java/C#
> don't have but that seem useful, not about Ocaml specifically.
Yes, I remember the talk. I know you weren't speaking specifically of
Ocaml, although I wasn't clear about that in my first email.
________________________________________________
Matthew D Moss
mo...@usermail.com
>- Linking of bytecode and native code would be good. Currently if you're using bytecode (debugging, compile speed, toplevel, etc.) and you need to optimize something, dropping to C is your only choice, which is silly.
I thought I might explain this one a bit in case it wasn't clear why you might be _forced_ to optimize something (as opposed to just wanting to). This is intimately related to the "debugger for native code" issue as well. I'm not trying to be condescending at all here, I just don't know if everybody on the list is used to writing time-dependent interactive code or not, and the thing I'm going to describe is kind of surprising at first (at least, it was for me when I figured it out, and it seems to be for other game developers). And, I'm not trying to beat the horse (since we know how Xavier loves that sort of thing :) of this specific bytecode-native linking thing, this is just using that as a jumping-off point. So, anyway, if you already know this, hit delete, if not, maybe it's useful to know...
The idea is if you have a system that's got an interactive feedback loop in it that has a certain type of time-dependent behavior, then there's a floor beneath which your performance can't drop or things don't work. I don't mean "things go slow so it's annoying", I mean the system actually stops working. All that's necessary is that you have a system that's time to complete is proportional to the time over which you'd like to run it. So, for example, physics simulation is like this: if you ask a [nontrivial] physics simulator to simulate from t0 to t1, the bigger t1-t0 is, the longer it will take to give you an answer back. Graphics can behave like this as well if you've got stuff like viewer-dependent level-of-detail; the longer your timestep is, the farther the camera moves, so the more level-of-detail changes your system needs to make, so the longer it takes to render the frame.
If you've got this kind of feedback loop in your application, and if your framerate drops below a certain magic threshold (that's dependent on the system, obviously), then it takes longer to generate each successive frame and things grind to a halt. In other words, you have the start time of t0 and the end time of t1, and you generate the frame at t1, and if it took longer than t1-t0 seconds, then t2-t1 is going to be even longer, so it takes even longer again, and you get this:
t1-t0 < t2-t1 < t3-t2 ...
And you're screwed. This is known among some in the game industry as "The Evil Feedback Loop." :) You can sometimes work around it with fixed steps and whatnot, but if you're trying to debug actual behavior where the user is interacting with the system, you're pretty much stuck with it at some point.
So, this relates to byte/native linking and native debugging because if you're using the bytecode compiler for debugging (or any of the other reasons) and you run into this problem, but the native code is fast enough, you have a nasty decision to make: you can either rewrite the slow part in C so you can keep using bytecode, or you can move to native code and give up the debugger.
Anyway, hopefully that is interesting to somebody...
I think I'm gonna do a gotcha page, but don't you think such
a page deserve his place on caml.inria.fr ?
Best regards,
--
Christian Gillot <cgi...@gruposbd.com>
GNU/Linux programmer
On Wed, Jan 23, 2002 at 10:35:34AM +0100, Christian Gillot wrote:
> 3. the exceptions are NOT polymorphics
> exception of 'a list is WRONG.
If they were, they could break the type system:
exception Foo of 'a list;;
try raise Foo [3] with Foo l -> "abc" :: l;;
--
Daniel de RAUGLAUDRE
daniel.de_...@inria.fr
http://cristal.inria.fr/~ddr/
You make it sound as if ML were the frontier of research .. surely
not. ML has been around for about as long as Unix, and more
revolutionary languages like Haskell approach a decade in existence.
Christian> I think I'm gonna do a gotcha page, but don't you think
Christian> such a page deserve his place on caml.inria.fr ?
It alredy exists:
http://caml.inria.fr/FAQ/FAQ_DEBUTANT-eng.html
At least 2 of your 3 problems are addressed there, and in its
companion FAQ_EXPERT.
--
Ian Zimmerman, Oakland, California, U.S.A.
GPG: 433BA087 9C0F 194F 203A 63F7 B1B8 6E5A 8CA3 27DB 433B A087
In his own soul a man bears the source
from which he draws all his sorrows and his joys.
Sophocles.
Mensaje citado por: Daniel de Rauglaudre <daniel.de_...@inria.fr>:
> > 3. the exceptions are NOT polymorphics
> > exception of 'a list is WRONG.
>
> If they were, they could break the type system:
>
> exception Foo of 'a list;;
> try raise Foo [3] with Foo l -> "abc" :: l;;
I agree with you, it's logic. But as a newbie you
easily stumble on this, because you just begin
to like the type polymorphism and suddenly you don't
understand why there is an exception (perdon me the pun)
to this rule with the exceptions. Of course there's always
good people like you or M. Monniaux (Thanks to him) to explain
this. That's what is called a gotcha, I guess.
Regards,
--
Christian Gillot <cgi...@gruposbd.com>
GNU/Linux developer
If the type system kept an annotation in types indicating if an
expression may raise an exception, it would be correct (the above
program would still be ill typed though). This annotation is just a kind
of disjunction
t or_raise ex1 or_raise ex2 ... it can be found in papers doing monadic
encoding of exceptions (and there are
two ways to do it: cps or disjunction which gives to kind of type
translation).
raise Foo [3] has type 'a or_raise Foo of int list
try raise Foo [3] with Foo l -> l has type int list.
This would be really nice, because the type system would infor you that
your program can not have uncaught exception.
(in soma cases)
To be not to verbose, you could disable by default the printing of
exceptions in types.
You should be carefull that a -> (b or_raise ex1) is different from (a
-> b) or_raise ex1 and that
(b or_raise ex1) -> a is just useless while (a -> (b or_raise ex1)) -> c
may be usefull.
--
Christophe Raffalli
Université de Savoie
Batiment Le Chablais, bureau 21
73376 Le Bourget-du-Lac Cedex
tél: (33) 4 79 75 81 03
fax: (33) 4 79 75 87 42
mail: Christoph...@univ-savoie.fr
www: http://www.lama.univ-savoie.fr/~RAFFALLI
-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.f=
r/FAQ/
To unsubscribe, mail caml-lis...@inria.fr Archives: http://caml.in=
ria.fr
Mensaje citado por: Ian Zimmerman <i...@speakeasy.org>:
>
> You make it sound as if ML were the frontier of research .. surely
> not. ML has been around for about as long as Unix, and more
> revolutionary languages like Haskell approach a decade in existence.
More or less I think so. In the industry functional programming is
sometimes something unknown (Java/C/C++/VB?). It's not a mainstream
language, and when you come from a imperative/OO world, the first step is
really hard. Because you've got to think in a another way.
Not to mention the fact that in the industry seldom use functional
programming...
I don't deny there's documentation (especially in French, merci) but
nothing in comparison with other functional languages (scheme and lisp
for instance). IMHO, the documentation is not really for beginners.
>
> Christian> I think I'm gonna do a gotcha page, but don't you think
> Christian> such a page deserve his place on caml.inria.fr ?
>
> It alredy exists:
>
> http://caml.inria.fr/FAQ/FAQ_DEBUTANT-eng.html
>
> At least 2 of your 3 problems are addressed there, and in its
> companion FAQ_EXPERT.
>
Right. Could be improved tought. I mean it's not addressing
the problems I had or others newbies had (example of the
record)
Note that the FAQ (which exist both in french and in english) are not included
in the sid debian package. (Sven: could you add this to the packages ?)
Regards,
--
Christian Gillot <cgi...@gruposbd.com>
GNU/Linux developer
> The GC performance predicability and smoothness is a huge looming shadow on the horizon that may or may not materialize, I have no idea.
Do you have any specific thoughts on this that you can share yet? Have you done any tests?
I've been trying to understand of the implications of garbage collection in soft real-time programs.
If the GC is not purely incremental -- if it has to do some sort of full collect every so often -- and if the time needed to do such a full collect is comparable to or longer than one game cycle, then you are stuck, aren't you? Is there anything you can do?
The time needed to do a full collect is proportional to the amount of live data in the program (right?). The only thing I think that could be done would be to move some of the data out into a C or C++ module.
Not necessarily. Most games have a series of "levels", or something
similar, with a pause for the human to congratulate himself, and for the
program to swap data around. If you can make the full collections run
(only) then, you're OK.
- ken
--
----------------------------------------------------------
Ken Rose Voice: 760.728.6993
VM Labs, Inc. FAX: 760.728.6993
520 San Antonio Rd. Email: ke...@vmlabs.com
Mountain View, CA 94040 : ro...@acm.org
Nope. It's just that the "conventional wisdom" is that GC will hurt performance, so I'm worried just on principle. :) I haven't seen any indication that it will yet, however.
As the other poster said, doing full collections between levels seems like a reasonable thing to try.
I'm also slightly worried about the "write barrier" thing, which I've seen posted about but don't fully understand yet. To avoid GC activity I may want to keep some arrays around and reuse them, but apparently as they migrate into the old heap then you get the write barrier thing going on. Hopefully this won't be a problem either, but I don't know yet (I don't know if I understand it correctly yet, either).
Lots of fun adventures on the horizon, I'm sure...just hopefully no show-stoppers. ;)
> > The GC performance predicability and smoothness is a huge looming
> > shadow on the horizon that may or may not materialize, I have no
> > idea. Do you have any specific thoughts on this that you can
> > share yet? Have you done any tests?
>
> Nope. It's just that the "conventional wisdom" is that GC will hurt
> performance, so I'm worried just on principle. :) I haven't seen any
> indication that it will yet, however.
>
> As the other poster said, doing full collections between levels
> seems like a reasonable thing to try.
>
> I'm also slightly worried about the "write barrier" thing, which
> I've seen posted about but don't fully understand yet. To avoid GC
> activity I may want to keep some arrays around and reuse them, but
> apparently as they migrate into the old heap then you get the write
> barrier thing going on. Hopefully this won't be a problem either,
> but I don't know yet (I don't know if I understand it correctly yet,
> either).
I have no real-world experience to share concerning OCaml's garbage
collector, but there's an informal description of how it works here:
http://para.inria.fr/~doligez/caml-guts/Sestoft94.txt
It's linked off the "Papers" section of the OCaml web site:
http://caml.inria.fr/ocaml/papers.html
Anyway, I'll speculate, because I've long pondered using GC in games:
based on that description, OCaml's GC is *exactly* the ideal type of
collector for interactive games. It's generational, which is good for
overall efficiency, and the old generation is collected incrementally,
which means it processes a single "chunk" at a time, rather than the
full heap. I haven't even looked at the API, but in theory the ideal
way to run a collector like this in a double-buffered game program
(like many console games) is to:
1) make sure the worst-case time to process a chunk is under say 2ms.
Do this by sizing the chunks appropriately or whatever. Disclaimer: I
have no idea what Ocaml GC's real-world latency is for processing a
chunk.
2) at the end of rendering, before displaying the back buffer, look at
the timer and decide whether you have 2ms to spare before the next
vsync. If so, then run the GC for one chunk -- it's practically free.
If not, then don't; hopefully you'll catch up in subsequent frames.
Basically, if your average allocation rate is below some threshold
(and you have some extra room on the heap to amortize any peaks), and
you run the GC enough, you'll *never* see a GC pause.
If you're triple-buffered, or you don't wait for vsync, then this
trick doesn't work, but in those cases you probably care much less
about an extra 2ms GC latency now and then.
The deal with a write barrier is that any time you write to a pointer
variable that's stored in the old generation of the heap, the GC must
know about it (so it can keep its incremental state synchronized). If
you're reading, or just writing data variables, the write barrier
should be irrelevant (although I don't know how it's implemented in
practice, so I'll shut up now).
-Thatcher