<mrvn>
"But, indeed, it should be understood as a type constraint." Doesn't that says it all?
<yezariaely>
mrvn: I meant the module type below.
<mrvn>
"val sum: 'a -> 'a -> 'a" declares a type, but "let sum: 'a -> 'a -> 'a =" constrains the type of sum.
<yezariaely>
thanks :)
<mrvn>
The constraint doesn't prevent the type inference to further narrow down the type to int -> int -> int
<yezariaely>
but the declaration, does, right?
<mrvn>
yes.
<yezariaely>
so, without the val part sum would not be polymorphic? (hmm if + would be polymorphic....)
<mrvn>
and int -> int -> int can't be unified (?) with the declared type 'a -> 'a -> 'a.
<yezariaely>
sure.
<mrvn>
if + where polymorphic then the infered type of sum would remain 'a -> 'a -> 'a
<mrvn>
let sum: 'a -> 'a -> 'a = fun x y -> assert false should work for example.
<yezariaely>
ah, I see. thank you
Simn has quit [Read error: Connection reset by peer]
malo has joined #ocaml
mcclurmc has joined #ocaml
bnoordhuis has joined #ocaml
cago has quit [Read error: Operation timed out]
bnoordhuis has quit [Ping timeout: 256 seconds]
octet8 has quit []
avsm has joined #ocaml
q66 has quit [Ping timeout: 246 seconds]
q66 has joined #ocaml
ontologiae has joined #ocaml
metasyntax has joined #ocaml
yacks has joined #ocaml
strobegen1 has joined #ocaml
talzeus has joined #ocaml
strobegen has quit [Ping timeout: 252 seconds]
avsm has quit [Quit: Leaving.]
avsm has joined #ocaml
bnoordhuis has joined #ocaml
<gasche>
ollehar: you there?
<gasche>
I looked at the bug you were talking about
<gasche>
the problem is fundamental: adding "expr -> lower_ident" to the grammar of expressions makes "match foo with x when p -> e" ambiguous about what "p->e" mean
<gasche>
I can fix it very easily by changing the module-using keyword to be --> instead of -> as suggested (and so can you by trivially modifying Fabrice's code)
<gasche>
of course, this won't protect you from assert false if --> is misused; the existing camlp4 code is very fragile, I suppose it was just a proof of concept, but anyway
<gasche>
without changing the syntax, there is no hope of getting a sane syntax extension
<gasche>
(another fix would be to change the lexer to detect the presence of spaces around the arrow and disambiguate this way; I do not need to point out that this is a batshit crazy bad idea.)
mchqwerty has quit [Quit: Odcházím]
mchqwerty has joined #ocaml
avsm1 has joined #ocaml
avsm has quit [Read error: Connection reset by peer]
cago has joined #ocaml
ontologiae has quit [Ping timeout: 240 seconds]
avsm1 has quit [Quit: Leaving.]
BitPuffin has joined #ocaml
<BitPuffin>
Hey guys
<BitPuffin>
can an ocaml program be modified while it is running like common lisp?
<ggole>
No.
<ggole>
The toplevel is the closest you can get, which isn't quite the same thing.
<flux>
well, via the dynamic loading mechanism you can load new code while it's running
<ggole>
That's useful, but it isn't really program modification.
<flux>
but that would mean (for your usage) the user would need to have the compilation tools around, which is maybe typically expected
<ggole>
You can't redefine a function in the debugger, for instance.
<gasche>
if you plan in advance for what should be modifiable, you can make those function references
<flux>
or you can do it like irssi, dump whole state to a file and then exec the binary itself, that reads the state and recovers open fds from the parent process :)
<gasche>
I'm not saying "we can do this to", but to some limit hotswapping designs actually work in statically-typed languages where this was unplanned for
<gasche>
yeah, or xmonad
<BitPuffin>
flux: Oh well I only want to modify while it is running during development
<flux>
(but that's quite different from modifying the program)
<flux>
bitpuffin, maybe your best bet is to make it work nicely in the interactive toplevel
<flux>
bitpuffin, what kind of modifications do you expect to do?
<flux>
not even toplevel can really replace a module or a function
<flux>
existing code will still call the code before the 'redefinition'
<BitPuffin>
flux: Well you did say that there is dynamic loading?
<flux>
you can really only introduce new symbols with the same names as before, but scoping rules apply
<BitPuffin>
flux: Basically lots of things, game logic scripting, changes to the renderer etc
<flux>
bitpuffin, there is a Dynlink module for loading a new module from a file. a plugin-mechanism.
<BitPuffin>
flux: so I can only add new stuff and not modify what's already going? :(
<gasche>
BitPuffin: I think in practice an approach where you design all your state to be serializable, and pray for save/restart to be fast enough is a reasonable path
<flux>
bitpuffin, yes
<gasche>
the short answer is "no you can't modify code", though in fact you can more or less do that in special case
<gasche>
(but that requires some level of expertise with the language and workarounds, and it's probably not worth the effort compared to the save-and-restart trick)
<gasche>
(given that game programming *already* requires you to be able to save the program state)
milosn_ has joined #ocaml
<flux>
well, if you plan to do it, it is somewhat easy. just use references to functions instead of actual functions as you suggested
<flux>
but that doesn't cover modifying types
<flux>
and I think it might end up being a pain in the behind..
<flux>
I mean, if you are planning to have a game that can change its behavior runtime, then maybe there are better approaches
milosn has quit [Ping timeout: 248 seconds]
<flux>
I don't know what they would be, though :-)
yezariaely has quit [Quit: Leaving.]
<BitPuffin>
flux: well no the game is not supposed to be able to change its behavior at runtime other than when it is being developed
<flux>
bitpuffin, ok.. so I imagine you have (say) a character that is moving and you want to change the game functionality without moving the character..
<BitPuffin>
common lisp had minor limitations with it's runtime changing stuff, you couldn't change inlined functions
<flux>
then I think gasche's suggestion about being able to save/restore game state is a good one
<flux>
I think it would be possible to make it pretty simple and seamless
<flux>
something like window closes, window opens, character is in same position as before
<flux>
(even that is possible to optimize if desired, but not probably essential for development)
<BitPuffin>
flux: Well another example would be having the game running and changing the value for how much force is applied when you jump and see the effectss immediately
<flux>
for that I think a good option is to have a global parameter system
<ggole>
That isn't hard to cover as a special case
<BitPuffin>
well that's only one case
<flux>
basically a system that allows you to modify any global interesting value
<BitPuffin>
I'd like to be able to change pretty much everything, even core engine stuff
<ggole>
In that case you'll have to plan pretty carefully
<BitPuffin>
shame that ocaml doesn't have that
<flux>
I think a save/restore-system workflow would work like: edit, compile, press F5 in the game -> one second later you have the upgraded version running in the same game state
<ggole>
You might be able to separate game state from engine from renderer state and save/restore or keep them over a code load
<adrien_oww>
hmmmmmmmmmmmmmmmm
<BitPuffin>
The reason I chose ocaml instead of lisp was because you have to go too much out of your way to make it statically typed
<flux>
the thing is that one needs to consider what happens when data structures are changed
<flux>
and that I think is a difficult problem to do automatically..
<ggole>
Well, in the general case it doesn't work
<ggole>
But you can cover some cases
<ggole>
CLOS has some support for updating objects
<flux>
erlang apparently has cool support for it
<flux>
AFAIK it even works pretty much the same
<flux>
your threads can call the next version of itself with whatever parameters
<flux>
but I could be wrong ;-)
<BitPuffin>
Hmm
<BitPuffin>
what about a very thin binding level that only stores state and loads the engine and game code in the compiled binary
<BitPuffin>
like a dynamic lib for the engine and logic etc
<BitPuffin>
that way it wouldn't need to serialize the data, only reload the libraries once they change
<flux>
that would be one way and it would enable more smooth transitions
<flux>
(but I think it would also be more work with perhaps dubious benefits)
<BitPuffin>
yeah because it would stay in memory
<BitPuffin>
yeah smoothness is not really a problem because it's only during development
<flux>
at least it would be easier to prevent the window from closing/reopning
<BitPuffin>
yeah
<BitPuffin>
hmmm
<BitPuffin>
is there anything that is stopping ocaml from getting the same kind of features that common lisp has in this case? or is it just that nobody has made it yet?
<flux>
well, let's say you have code type t = { a : int } let foo a = a.a = 42
<flux>
then you load code type t = { a : string }
<flux>
what should happen?
<ggole>
Static typing and binding is a pretty big hurdle
<BitPuffin>
flux: what would lisp do?
<flux>
it doesn't have that kind of types AFAIK
<BitPuffin>
Well no but does that mean that if you declamate types in lisp functions the changing at runtime breaks down?
<ggole>
Lisp keeps enough information to recover types at runtime
<ggole>
OCaml doesn't
<ggole>
So its hard/impossible to do the right thing
<gasche>
well
<gasche>
if you decide to change OCaml's implementation to make this kind of use possible
<BitPuffin>
ggole: yes but you can make lisp statically typed with declamation, which makes it run faster
<gasche>
you could also change the value representation to keep type information; that is not that hard to do
<ggole>
Declarations aren't types in the same sense
<mrvn>
What do you want it to do? Give a type error when you redefine t?
<gasche>
hnrgrgr worked on type-safe marshalling for OCaml, it isn't very far from that
<mrvn>
flux: What you need is a framework for versioned structures and functions that convert between versions.
<BitPuffin>
hmmm
w0rm_x has joined #ocaml
<BitPuffin>
but yeah it wouldn't even work in common lisp then
<BitPuffin>
if you have a function in lisp that declares a parameter to be a certain type in a function
<mrvn>
That also applies to save games and network protocol. You want to be able to load older save games and talk with older/newer clients.
<BitPuffin>
then if you change that function at runtime to take some other value and other code accordingly to make it work, then the variables will still hold values of the wrong type
cago has left #ocaml []
<BitPuffin>
It is a very tricky problem
<BitPuffin>
but one worth solving I think
<BitPuffin>
imagine working on a renderer and seeing the changes in real time
<BitPuffin>
that would allow for such an experimental workflow
<BitPuffin>
as for the game logic
<BitPuffin>
maybe I can just use the interpreter parts of ocaml for changing stuff like jumping forces and stuff, and then compile that in the end
<mrvn>
BitPuffin: I've been thinking of writing an interactive interpreter/editor like that. You would write your code and e.g. write "let foo x = #FIXME ..." and then run it. When foo gets called it would jump back into the editor and prompt you to implement it.
<mrvn>
And you could inspect x and the environment at that point.
<BitPuffin>
mrvn: yeah that would be kind of cool. Although I wouldn't want to leave my vim :P
<BitPuffin>
mrvn: and it would be great if it somehow integrated with regular ocaml stuff. So that you can compile it to a state where it is (almost) optimal performance, but it keeps enough so that it can reverse itself and change and runtime, and then compile itself down to the almost optimal state
<BitPuffin>
I dunno
<BitPuffin>
maybe that's not possible
<BitPuffin>
Or well it should be
<mrvn>
that makes no sense
<BitPuffin>
I think it does
<BitPuffin>
maybe I didn't say it in a way that makes sense
<BitPuffin>
But I mean when you compile ocaml code, it probably doesn't keep what type something should be in the final machine code right?
shinnya has joined #ocaml
<mrvn>
BitPuffin: not at runtime
djcoin_ has quit [Quit: WeeChat 0.4.1]
<BitPuffin>
mrvn: but you COULD have it keep that information
<mrvn>
The cmi files contain the type
<mrvn>
and the tags file the type within functions or you could infere that simply from the source as needed.
<BitPuffin>
So that way you could have it know at runtime that this variable needs to change into that type in order for things to keep working. And maybe it's a big long list of variables that changed, then you write a simple converter function that takes all those variables and changes them
<mrvn>
hardly.
<BitPuffin>
why not?
<BitPuffin>
I don't see how it isn't possible
<mrvn>
because when you change the type of something, e.g. from int to float, at the top then you need to change a ton of code so it use +. instead of + and the change propagates through a lot of code and data structures.
<BitPuffin>
mrvn: yeah but changing that part happens before you reload, because it wouldn't reload until it actually compiles
<mrvn>
You get ripple effects.
<mrvn>
And the change in code can make it take other code paths that it didn't take before so you would never get the type you got now.
<BitPuffin>
mrvn: so then when it compiles, it reloads and prompts you to write an expression that will convert this list of variables that have the old type into a form that is usable in the new system
w0rm_x has quit [Read error: Operation timed out]
<mrvn>
that might be millions of variables
<BitPuffin>
mrvn: yes that's why you write one expression for each type
<mrvn>
and you would have to trace where every value came from through every operation.
<BitPuffin>
mrvn: so maybe there is a million different types, at that point it would be better to just restart the program
<gour>
uhh...such complexity for questionable gain :-)
<mrvn>
I think restarting would be the only feasable thing
<BitPuffin>
yeah it doesn't sound optimal
strobegen1 has quit [Ping timeout: 260 seconds]
<BitPuffin>
but there has to be a good way to do it
<BitPuffin>
because being able to do interactive programming is a huge gain :P
<mrvn>
I can see a middle ground. You basically set a breakpoint at some function. Then when it traps you can trace that function and edit it or edit the input data and rerun the function again and again from the state of the trap.
<mrvn>
But leaving the function would then restart.
<mrvn>
That would give you a smaller scope and limited amount of changes to consider.
<BitPuffin>
hmm
mchqwerty has quit [Quit: Odcházím]
<BitPuffin>
mrvn: but then you'd have to set that function manually
<BitPuffin>
maybe for my usecase maybe it is just better to separate my engine in to glue code which also keeps track of the state in the game
strobegen has joined #ocaml
<BitPuffin>
the bytecode interpreter for ocaml can be used from the natively compiled code right?
<adrien_oww>
I don't think so
<adrien_oww>
well, at least I don't think you can use it to run bytecode dynamically
<BitPuffin>
so you can't use it as a scripting language?
levi has joined #ocaml
BitPuffin has quit [Read error: Operation timed out]
_andre has quit [Ping timeout: 260 seconds]
talzeus has quit [Remote host closed the connection]
_andre has joined #ocaml
maufred has quit [Remote host closed the connection]
ocp has joined #ocaml
demonimin has quit [Ping timeout: 245 seconds]
demonimin has joined #ocaml
bnoordhuis has quit [Ping timeout: 272 seconds]
milosn_ is now known as milosn
ulfdoz has joined #ocaml
ollehar has quit [Ping timeout: 259 seconds]
zarul has quit [Ping timeout: 256 seconds]
Simn has joined #ocaml
ohama has quit [Ping timeout: 256 seconds]
ohama has joined #ocaml
troydm has quit [Ping timeout: 264 seconds]
nisstyre has quit [Disconnected by services]
yours_truly has joined #ocaml
vpm has quit [Quit: co'o]
ocp has quit [Ping timeout: 260 seconds]
vpm has joined #ocaml
AltGr has left #ocaml []
Neros has quit [Ping timeout: 260 seconds]
sepp2k has quit [Quit: Konversation terminated!]
bnoordhuis has joined #ocaml
bnoordhuis has quit [Ping timeout: 268 seconds]
zpe has joined #ocaml
Neros has joined #ocaml
malo has quit [Quit: Leaving]
troydm has joined #ocaml
dsheets has quit [Quit: Leaving]
BitPuffin has joined #ocaml
Drup has joined #ocaml
shinnya has quit [Ping timeout: 272 seconds]
ocp has joined #ocaml
mfp has quit [Ping timeout: 240 seconds]
saml has quit [Quit: Leaving]
Drup has quit [Ping timeout: 272 seconds]
zarul has joined #ocaml
mfp has joined #ocaml
Drup has joined #ocaml
yours_truly has quit [Quit: Leaving]
ggole has quit []
pango has quit [Remote host closed the connection]
troydm has quit [Ping timeout: 264 seconds]
pango has joined #ocaml
skchrko has quit [Quit: Leaving]
mcclurmc has quit [Quit: Leaving.]
sgn has joined #ocaml
<thomasga>
any idea how I can instantiate a function: val f: (module S with type t = 'a) -> 'a -> unit
<thomasga>
when I have S.create: unit -> t
saml has joined #ocaml
manizzle has quit [Ping timeout: 252 seconds]
troydm has joined #ocaml
darkf has joined #ocaml
peterbb has joined #ocaml
bobzhang1988 has joined #ocaml
<jpdeplaix>
thomasga: no, I think there is no ways. You need a functor
w0rm_x has joined #ocaml
sgn has quit [Ping timeout: 250 seconds]
<smondet>
thomasga: not if sure it is what you want
<smondet>
# module type S = sig type t val create: unit -> t end
<smondet>
let f: type a. (module S with type t = a) -> a -> unit =
<smondet>
fun m x ->
<smondet>
let module M = (val m : S with type t = a) in
<smondet>
if M.create () = x then printf "bouh" else printf "pas bouh"
<smondet>
;;
<smondet>
module type S = sig type t val create : unit -> t end
<smondet>
val f : (module S with type t = 'a) -> 'a -> unit = <fun>
<thomasga>
jpdeplaix: indeed I'm not totally sure how to use a functor in this case either
ulfdoz has quit [Ping timeout: 260 seconds]
peterbb has quit [Ping timeout: 268 seconds]
<smondet>
thomasga: with let x = (module X: S with type t = int)
<smondet>
f type checks
<smondet>
(and f x 42 prints "42")
w0rm_x has left #ocaml []
<smondet>
still not sure if it fits what you want :)
<thomasga>
actually I wanted to type g x
<thomasga>
but that's work when the type are not abstract
<thomasga>
hum
<thomasga>
I'll see if I can apply that to my issue :-)
<thomasga>
thx!
ohama has quit [Ping timeout: 268 seconds]
madog has joined #ocaml
ohama has joined #ocaml
manizzle has joined #ocaml
bnoordhuis has joined #ocaml
peterbb has joined #ocaml
gour has quit [Quit: WeeChat 0.4.1]
Drup has quit [Quit: Leaving.]
Drup1 has joined #ocaml
manizzle has quit [Write error: Broken pipe]
manizzle has joined #ocaml
metasyntax has quit [Quit: Leaving]
bobzhang1988 has quit [Read error: Operation timed out]
strobegen1 has joined #ocaml
strobegen has quit [Read error: Operation timed out]
ulfdoz has joined #ocaml
wolfnn has quit [Read error: Operation timed out]
saml has quit [Remote host closed the connection]
w0rm_x has joined #ocaml
BitPuffin has quit [Ping timeout: 240 seconds]
ollehar has joined #ocaml
Drup1 is now known as Drup
szacun has joined #ocaml
strobegen1 has quit [Quit: Leaving.]
ocp has quit [Ping timeout: 246 seconds]
thomasga has quit [Quit: Leaving.]
<szacun>
Hi! I am writing function to add a number to appropriate list depending whether the number is odd or even. I try do it with as few characters as possible and i would like to ask if there is a way to do it like this: http://pastebin.com/LLxTwc6M and maybe i have only some syntax error, or if this has completly no sense
<szacun>
actually i wrote this code to only show idea how i want to resolve a problem of choosing a list to add an element, i know that adding to list basing on parity may be done easier
Neros has quit [Ping timeout: 268 seconds]
Simn has quit [Quit: Leaving]
madog has left #ocaml []
<szacun>
ok, i'll come back tomorrow...
Dulles has joined #ocaml
szacun has quit []
ulfdoz has quit [Ping timeout: 260 seconds]
shinnya has joined #ocaml
Dulles has quit [Ping timeout: 245 seconds]
stevej has quit [Quit: Computer has gone to sleep.]