<jpdeplaix>
whitequark: the final binary is now really huge: 20Mo :D
zpe has joined #ocaml
yminsky has joined #ocaml
NoNNaN has quit [Ping timeout: 240 seconds]
yminsky has quit [Client Quit]
zpe has quit [Remote host closed the connection]
zpe has joined #ocaml
zpe has quit [Ping timeout: 272 seconds]
NoNNaN has joined #ocaml
ontologiae has joined #ocaml
testcocoon has quit [Quit: Coyote finally caught me]
testcocoon has joined #ocaml
cesar_ has joined #ocaml
cesar_ is now known as Guest85137
testcocoon has quit [Quit: Coyote finally caught me]
Guest85137 has quit [Ping timeout: 265 seconds]
testcocoon has joined #ocaml
wormphlegm has joined #ocaml
ulfdoz has joined #ocaml
wormphlegm has quit [Read error: Operation timed out]
ontologiae has quit [Read error: No route to host]
baz_ has quit [Remote host closed the connection]
klltkr has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
baz_ has joined #ocaml
zpe has joined #ocaml
Anarchos has joined #ocaml
strobegen has quit [Quit: Leaving.]
Qrntz_ has joined #ocaml
Qrntz_ has quit [Client Quit]
Snark has quit [Quit: leaving]
Neros has joined #ocaml
Yoric has joined #ocaml
Yoric has quit [Ping timeout: 245 seconds]
wormphlegm has joined #ocaml
demonimin has joined #ocaml
q66_ has joined #ocaml
q66 has quit [Disconnected by services]
q66_ is now known as q66
zpe has quit [Remote host closed the connection]
zpe has joined #ocaml
ulfdoz has quit [Ping timeout: 264 seconds]
BitPuffin has quit [Ping timeout: 264 seconds]
zpe has quit [Ping timeout: 272 seconds]
<whitequark>
jpdeplaix: hmm, interesting
peterbb has joined #ocaml
<whitequark>
I don't think the functions you have in LLVM.ml are generally useful
<whitequark>
re huge binary: yes, that's very much expected.
<whitequark>
complete debug build of LLVM takes about 700 Mb of executable code
<whitequark>
for release build it's 120 or so
<whitequark>
your binary is only linked with the components you need, so it's way smaller.
Yoric has joined #ocaml
baz_ has quit [Ping timeout: 264 seconds]
csakatoku has joined #ocaml
ulfdoz has joined #ocaml
cesar_ has joined #ocaml
cesar_ is now known as Guest44978
Guest44978 has quit [Ping timeout: 272 seconds]
zpe has joined #ocaml
csakatoku has quit [Remote host closed the connection]
csakatoku has joined #ocaml
zpe has quit [Remote host closed the connection]
zpe has joined #ocaml
zpe has quit [Read error: Connection reset by peer]
zpe has joined #ocaml
zpe has quit [Remote host closed the connection]
zpe has joined #ocaml
csakatoku has quit [Remote host closed the connection]
csakatoku has joined #ocaml
zpe has quit [Ping timeout: 240 seconds]
csakatoku has quit [Read error: No route to host]
csakatok_ has joined #ocaml
Kakadu has quit []
rand000 has quit [Ping timeout: 264 seconds]
csakatok_ has quit [Ping timeout: 272 seconds]
peterbb has quit [Ping timeout: 264 seconds]
ggole has joined #ocaml
yezariaely has joined #ocaml
paddymahoney has quit [Read error: Operation timed out]
gour has quit [Disconnected by services]
gour_ has joined #ocaml
gour_ is now known as gour
zpe has joined #ocaml
Drup has joined #ocaml
tane has joined #ocaml
peterbb has joined #ocaml
Yoric has quit [Ping timeout: 252 seconds]
peterbb has quit [Read error: Operation timed out]
klltkr has joined #ocaml
avsm has joined #ocaml
ulfdoz has quit [Ping timeout: 265 seconds]
ygrek has joined #ocaml
cesar_ has joined #ocaml
cesar_ is now known as Guest25543
Guest25543 has quit [Ping timeout: 264 seconds]
peterbb has joined #ocaml
platypine has joined #ocaml
platypine has quit [Ping timeout: 240 seconds]
avsm has quit [Quit: Leaving.]
avsm has joined #ocaml
avsm has quit [Client Quit]
Neros has quit [Ping timeout: 272 seconds]
zpe has quit [Remote host closed the connection]
zpe has joined #ocaml
rand000 has joined #ocaml
zpe has quit [Ping timeout: 272 seconds]
ygrek has quit [Ping timeout: 272 seconds]
troydm has joined #ocaml
ggole has quit []
klltkr has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
avsm has joined #ocaml
Yoric has joined #ocaml
bjorkintosh has quit [Quit: Leaving]
testcocoon has quit [Quit: Coyote finally caught me]
rand000 has quit [Ping timeout: 245 seconds]
testcocoon has joined #ocaml
shinnya has quit [Ping timeout: 244 seconds]
avsm has quit [Quit: Leaving.]
mildfate has joined #ocaml
mildfate has left #ocaml []
zpe has joined #ocaml
zpe has quit [Ping timeout: 248 seconds]
platypine has joined #ocaml
bjorkintosh has joined #ocaml
cesar_ has joined #ocaml
cesar_ is now known as Guest80163
Guest80163 has quit [Remote host closed the connection]
peterbb has quit [Ping timeout: 245 seconds]
baz_ has joined #ocaml
zpe has joined #ocaml
avsm has joined #ocaml
zpe has quit [Remote host closed the connection]
zpe has joined #ocaml
zpe has quit [Read error: Connection reset by peer]
zpe has joined #ocaml
zpe has quit [Remote host closed the connection]
zpe has joined #ocaml
thelema_ has quit [Remote host closed the connection]
thelema has joined #ocaml
zpe has quit [Ping timeout: 265 seconds]
baz_ has quit [Remote host closed the connection]
yezariaely has quit [Quit: Leaving.]
avsm has quit [Quit: Leaving.]
Yoric has quit [Ping timeout: 245 seconds]
nikki93 has joined #ocaml
Arsenik has quit [Remote host closed the connection]
Arsenik has joined #ocaml
baz_ has joined #ocaml
cesar_ has joined #ocaml
cesar_ is now known as Guest93990
rand000 has joined #ocaml
osa1 has joined #ocaml
Drup has quit [Read error: Connection reset by peer]
rand000 has quit [Ping timeout: 252 seconds]
baz_ has quit [Remote host closed the connection]
rand000 has joined #ocaml
Drup has joined #ocaml
baz_ has joined #ocaml
osa1 has quit [Ping timeout: 240 seconds]
mcclurmc has joined #ocaml
rand000 has quit [Ping timeout: 264 seconds]
wormphlegm has quit [Quit: leaving]
wormphlegm has joined #ocaml
peterbb has joined #ocaml
zpe has joined #ocaml
wormphlegm has quit [Quit: leaving]
wormphlegm has joined #ocaml
avsm has joined #ocaml
zpe has quit [Ping timeout: 248 seconds]
avsm has quit [Ping timeout: 264 seconds]
wormphlegm has quit [Quit: leaving]
wormphlegm has joined #ocaml
<jle`>
ocaml's strictness seems to be biting me. i'm writing a parser combinator system to parse a possibly infintely recursive grammar but it timeouts when loading the function
wormphlegm has quit [Client Quit]
wormphlegm has joined #ocaml
<mrvn>
how can that be a fault of the types?
<jle`>
is this because of this? or is this another problem?
<gour>
isn't it possible to use laziness when needed?
<jle`>
not sure, i'm basically porting over something i've written in haskell
<jle`>
i would expect infinitely recursive functions to be possible right?
<gour>
jle`: just curious, why you've left haskell?
<adrien>
you mean strict as opposed to lazy?
<jle`>
although admittedly i am not revealing too many details
<jle`>
gour: haven't left haskell, it's for a course heh.
<gour>
ahh, ok
<mrvn>
jle`: then you need lazy
* gour
left haskell :-)
testcocoon has quit [Quit: Coyote finally caught me]
<jle`>
really?
<jle`>
any reason? heh
<jle`>
my time in ocaml land has brought me respect and understandin, but nothing too convincing to cause me to switch
<mrvn>
if you evaluate a infinite recursive function then it takes infinite time
<jle`>
mrvn: this is in the loading of the function into the interpreter, not actual evaluation
<gour>
yep...played with it some years ago, but there was too many monad-stuff and few potential contributors for the project jsut run away in fear. :-) another reason was poor support for gui bindings
<gour>
jle`: ocaml seems to be more pragmatic for real-world
Leonidas has quit [Ping timeout: 245 seconds]
Leonidas has joined #ocaml
testcocoon has joined #ocaml
<gour>
let me also say that i was in #haskell at the time with < 100 users, later discovering >500 and lot of posts in haskell-cafe made me reluctant to come back :-)
<jle`>
practical/pragmaticness is the argument i always have heard yeah. how haskell seems to try really hard to be as unpractical as possible
<jle`>
and the smaller pool of contributors is probably a good reason as well
<gour>
jle`: the haskell code in practice which i've seen always seems to lost lot of its elegance while solving textbook exercises :-)
<jle`>
we're getting there ;) one neat thing is that i feel like we are constantly discovering new ways to recapture the elegance
ehm is now known as maurer
mk270 has left #ocaml []
<jle`>
that kind of ... motion/atmosphere is a part of the excitement for me
<jle`>
but maybe it's here in ocaml too
wormphlegm has quit [Quit: leaving]
<jle`>
but never got enough of the community/ecosystem
wormphlegm has joined #ocaml
osa1 has joined #ocaml
<gour>
jle`: in ocaml?
wormphlegm has quit [Client Quit]
<jle`>
oh in haskell
wormphlegm has joined #ocaml
<gour>
i find that opam, ocaml platform, several build systems...merlin are very healthy signs
klltkr has joined #ocaml
<mrvn>
haskell tries to build the most optiming haskell compiler in the world. ocaml goes for simplicity
<gour>
the last remaining part (for me) is to see some more support for some c++ gui bindings (qt or wx)
<gour>
by nature, i'm more attracted towards simplicity
<maurer>
So, not to shit on ocaml, but just feel the need to be a dissenting voice: I have to use ocaml for work because my group's codebase is in it. However, I find ocaml to be massively less practical for real world work than haskell.
<jle`>
did not mean to start a language war :)
wormphlegm has quit [Client Quit]
wormphlegm has joined #ocaml
<maurer>
(I actually have a complaint file on my machine that I've started gradually filling up to deal with my rage at ocaml's impracticality when I encounter it)
<gour>
maurer: how is it so? just curious...
<maurer>
gour: It's kind of a sum of little things, but examples include:
<maurer>
1.) No native threading support. I've got 8 cores, but if I want to use them, I'll have to do state synch and serialization manually and do it with multiprocessing
<adrien>
s/No native threading support./Lock on the garbage collector/
<maurer>
2.) Most libraries are missing common or expected functions, e.g. map does not have a function of the form "lookup : 'a t -> key -> 'a option"
<gour>
there is some work going on, afaik, to fix that remedy
<maurer>
err, "Map"
<mrvn>
gour: not realy. They ocaml stdlib only implements what the compiler actualy needs basically.
<mrvn>
you need batteries or core
<maurer>
Since there's no laziness, you need to use macros in order to have debug messages/checks that aren't printed if debug flags are off
<gour>
maurer: i was thinking about core lib and new branch in compiler
<mrvn>
maurer: huh? There is lazyness but what has that got to do with debug prints?
<maurer>
mrvn: For example, if I am doing an inference engine and I want to print out my context
<adrien>
maurer: there's "find" in Map; only difference is that it returns 'a and might raise Not_found
<maurer>
this will compute (Context.to_string ctx) every time
<maurer>
adrien: Yes, which means I need to use exceptions every time I want to do a search on a map
<jle`>
i can't say too much about practicality becuase i haven't done enough in both to really compare. but my own personal preference lies in simply the theoretical aspects of the languages. and i love all of the worlds that open up from "strict" purity and the abstractions to deal with it. and monads. so it's mostly a language design/theoretical thing
<mrvn>
maurer: because ocaml has no notion of functions without side effects.
<jle`>
anyways my original question, it's possible for the interpreter to hang while even parsing an infinitely recursive function?
<maurer>
mrvn: Sure, but the point is that at the end of the day, I still have to either use macros or comment out my debug statements rather than setting a flag
<maurer>
since to_string is a potentially expensive operation there
<maurer>
Now, this gets made worse by the fact that native code profiling gives little insight into what's actually going wrong, because usually it just displays that all the time is taken in the ocaml runtime
<maurer>
if you want actual profiling of your ocaml code, you need to do it using the bytecode profiler, which will not run if you are using macros
testcocoon has quit [Quit: Coyote finally caught me]
<adrien>
jle`: parsing, no; but evaluating it, yes; can you pastebin the code?
<Drup>
maurer: Map.Exceptionless.find
<Drup>
rebind at will
<Drup>
(I do)
<adrien>
maurer: I have rarely seen all my application time taken by the runtime; if that was by the alloc functions, tuning the GC can help a lot (after trying to cut down allocations a bit but there's no upstream memory profiling currently)
<maurer>
adrien: In my current application, 34% of the time is taken in compare_val
<maurer>
adrien: and something like 20% in the gc
<Drup>
did you specialized the comparaison function ?
testcocoon has joined #ocaml
<mrvn>
Drup: obviously not
<Drup>
most your rants are just misinformations, for now. You can rant if you want, that's fine, but you can also just ask if you are doing something obviously wrong.
<maurer>
Drup: ? I started ranting because someone explicitly asked me to start doing so
<Drup>
maurer: well, you did rant on paper for yourself :p
<Drup>
ok, I was not clear, it was not agressive or something, just that, it's better to actually ask. Some stuff in the ocaml community are very badly documented and just "common knowledge" and you need to see it done by someone else to understand it
<Drup>
(tipically, the whole specialization stuff)
<maurer>
Drup: Yes, so that every time I discovered something new and broken (like List.map not being tail recursive, or like stack traces stopping at 100-1000 entries if you accidentally fail to terminate)
<maurer>
I would put it there because asking typically resulted in "that is just how this works, sorry"
<Drup>
you can use Batteries' List.map, which is tail recursive
<Drup>
(you see ? :D)
<maurer>
Yes, this is what I do now
<maurer>
But "there is a workaround" is different from "this is not wrong"
<Drup>
Oh, I agree, I rant on a regular basis on the state of the standard library too.
<maurer>
And about the lack of threading, and the fact that the only working profiling mode is incompatible with macros, which are necessary due to lack of other language features?
<gour>
isn't it similar situation within every programming language's community?
<Drup>
(I still don't get the whole macro point, though)
<maurer>
Drup: Try using camlp4 and then doing bytecode profiling
* gour
is sure there is no perfect prog. lang.
<maurer>
Drup: the compiler will flat out refuse
<adrien>
that should *not* happen
<maurer>
ocamlcp: profiling is incompatible with the -pp option
<maurer>
gour: Honestly, the only major issues I've found with haskell are the antimodularity of typeclasses, and the fact that the laziness is non-optional
<gour>
maurer: you're happy with e.g. cabal?
<maurer>
gour: Not super happy with it, but happier than I am with opam :P
<maurer>
gour: and at least it has variant tools like cabal-dev that can mask most of the problems at the expense of a little slowdown
<adrien>
we should probably buy a few SEO books
<gour>
maurer: heh, ok then. wish you that you could move fully to haskell ;)
<adrien>
it's not terribly difficult to create a documentation page that matches "compare_val", "slow", "profiling", ...
<gour>
maurer: cabal still does not have 'uninstall' ?
<maurer>
gour: I mean, ideally yes, but I still have to use ocaml day to day because I work on a huge chunk of ocaml code that won't get converted any time soon
<adrien>
maurer: ah, right; but you can pre-process the files before (I agree it's not very nice)
<maurer>
gour: I think not.
<adrien>
that said I have something to try
<gour>
maurer: well, perseverance helps ;)
<adrien>
also, I think you can link with a profile-mode runtime
<adrien>
likeusr/lib64/ocaml/stdlib.p.a
<gour>
maurer: are dons, kolmodin, dcoutts, shapr.. still active?
<maurer>
adrien: Yes, but sadly I have to do that manually because our build system (OCamlMakefile) does not understand this caveat
<maurer>
gour: don't know about kolmodin, but the rest are
<mrvn>
maurer: I'm sure that lets you add compiler options
<gour>
maurer: kolmodin was one of the main guys behind gentoo-haskell
<maurer>
mrvn: Sure, but the problem is that I'd need to do separate passes
<maurer>
gour: Ah. I still use that overlay, and it's maintained
<maurer>
gour: haven't checked in on the devs though
<mrvn>
maurer: then you are doing it wrong
<gour>
there was/is no party in regard to RWO?
<maurer>
mrvn: ? I was _just_ advised to do separate passes
<adrien>
mrvn: actually, no
<adrien>
the -pp option is not supported. If you need to preprocess your source files, you will have to do it sepa‐ rately before calling ocamlcp or ocamloptp.
<maurer>
Yeah. We are using -pp right now, and that is what our build system knows how to do w/rspt to macros
<bernardofpc>
Drup> you can use Batteries' List.map, which is tail recursive -> Batteries will do a lot of "caml_modify", won't it ? Isn't it better to rev . revmap ?
avsm has joined #ocaml
<bernardofpc>
(something to do about modifying pointers and being sure that they are not pointing to the "old generation")
<kerneis>
maurer: out of curiosity, do you work in industry or academia?
<maurer>
kerneis: Academia
<Drup>
bernardofpc: I'm not sure it's better, no
<maurer>
kerneis: I work on BAP, if you've heard of it
nikki93 has quit [Remote host closed the connection]
<mrvn>
itsn't Bta.List.map optimized to do chunks rekursively and then merge them with modify?
<maurer>
kerneis: but I have used haskell (as well as other languages) in industry internships
mcclurmc has quit [Remote host closed the connection]
<Drup>
bernardofpc: you don't really want to know, it's done with some magic :/
<bernardofpc>
that part I do know
<mrvn>
bernardofpc: List.rev is expensive for long lists
<adrien>
I don't understand which decision has lead to making ocamlcp refuse -pp
<bernardofpc>
but as for "doing a chunk and then checking with modify", last time I read .s it did not do modify in chunks
<adrien>
it really makes no sense
<mrvn>
bernardofpc: if you trigger a GC collection
<adrien>
also, ocamlfind ocamlcp doesn't work around it
nikki93 has joined #ocaml
baz_ has quit [Remote host closed the connection]
<bernardofpc>
mrvn: right
<bernardofpc>
(then you pay double collections because you will trigger again in the map part)
<bernardofpc>
(well, not so much if your map reduces size a lot)
<mrvn>
worse with a compaction
<Drup>
maurer: BAP, BIL, that's some names I can get along with <3
<maurer>
Yeah, basically my current work is attempting to reconstruct types from compiled binary code
<maurer>
Speaking of which, I should be writing that paper and not talking about ocaml >_>
<jle`>
adrien: ah i see it. it is a function that infinitely recurses to create a function
<adrien>
maurer: there's the code at http://caml.inria.fr/mantis/view.php?id=1465 ; modifying ocamlmakefile should be trivial ; you'll have to use the '-impl' option to tell ocamlcp _and_ ocamlprof that the file is to be treated as if it were a .ml file
<jle`>
so the function that it returns references itself infinitely potentially
<adrien>
:)
<jle`>
in practice it consumes a finite input so it won't ever actually go on forever
BitPuffin has joined #ocaml
<jle`>
but in "returning" the function it never returns the fully formed funcon
<jle`>
if that makes sense
<adrien>
if you're goint to put that on a web server, can you give me the address of the server? :)
tobiasBora has joined #ocaml
<tobiasBora>
Hello,
chrisdotcode has quit [Remote host closed the connection]
<jyeo>
I have a n00b question
<jyeo>
how do i fix this type error?
<jyeo>
Error: This expression has type
<jyeo>
Camlp4_import.Parsetree.structure =
<jyeo>
Camlp4_import.Parsetree.structure_item list
<jyeo>
but an expression was expected of type
<jyeo>
Parsetree.structure = Parsetree.structure_item list
<jyeo>
Type Camlp4_import.Parsetree.structure_item
<jyeo>
is not compatible with type Parsetree.structure_item
<Drup>
jyeo: context ?
<jyeo>
I am trying to type check a Camlp4 str_item type
<jyeo>
i am using Typemod.type_structure
skchrko has quit [Quit: Leaving]
gour has quit [Quit: WeeChat 0.4.1]
rand000 has joined #ocaml
wmeyer has joined #ocaml
<tobiasBora>
I'd like to know, is there a way to automatiquely generate a compiled function ?
<wmeyer>
hi
<tobiasBora>
Hi ;-)
<tobiasBora>
I mean,
<tobiasBora>
I've a program which make huge computes and a function is used everywhere in my program but always with something changing
<wmeyer>
tobiasBora: yes, closures are dynamically created functions. But I don't exactly follow what you mean.
<wmeyer>
ah partial specialisation you mean
<tobiasBora>
For exemple sometimes I need to copy an array, sometimes It's useless
<wmeyer>
or caching arguments?
<tobiasBora>
Sometimes the counting function is not the same...
<tobiasBora>
So for the moment I do like you seems to say wmeyer : I put functions in argument
<Drup>
tobiasBora: are you sure it's actually costing you, performance wise ?
<tobiasBora>
but it's a recursive function, and I beleave it costs time
<tobiasBora>
to put functions in parameter
<jyeo>
ugh i found my solution. Obj.magic
<tobiasBora>
I didn't though before, but I've two version and the one with explicit function is maybe 10 times faster...
<Drup>
jyeo: Obj.magic is never a solution.
<jyeo>
Drup: why not
<mrvn>
functions as arguments aren't inlined. that can be expensive
<jyeo>
it works
<wmeyer>
so tobiasBora, normally, you have a penalty using combinators, but with partial specialisation you can lift it
<wmeyer>
as mrvn says the compiler is able to specialise the function by inliinig the arguments
<mrvn>
wmeyer: no, it isn't
<wmeyer>
iniling the function that are passed (in some cases maybe)
<mrvn>
or rather, it doesn't.
<Drup>
it will be, soon :p
<tobiasBora>
mrvn: I though it was but indeed it doesn't seems to be...
<wmeyer>
not OCaml but Mlton yes
<wmeyer>
it's not easy in general case
<tobiasBora>
wmeyer: a combinator is the kind of function I use ? (always the same)
<wmeyer>
you have to propagate the arguments, and specialise function for some permutation, and then maybe leave the default case
<Drup>
jyeo: Obj.magic is a way to break the type system. it's an escape hook you should never use if everything was perfect.
<wmeyer>
Obj.magic shall be never used
<jyeo>
Yea, but I am pretty sure Camlp4_import.Parsetree should be unified with Parsetree
<mrvn>
not if you use the module name inside the module
<wmeyer>
that's bad jyeo
<wmeyer>
there is always a way (possibly incovenient) to avoid it
<wmeyer>
and it should be used, amounts of work to do it always pays off
<jyeo>
How should i avoid it then?
<Drup>
(is there a online documentation somwhere for camlp4 ? :/)
<tobiasBora>
wmeyer: Oh that's a good idea... You mean for example, if my function is my_function : fonc1 fonc2 arg1 arg2, I create an other function my_fonc2 = my_fonction fonc1 fonc2 ? And it's as efficient as manual definition ?
<wmeyer>
jyeo: you ask me? It's easy, explicit conversion.
<jyeo>
wmeyer: >_<
<jyeo>
easier said than done
<wmeyer>
jyeo: sorry, it should be easy. If you have a variant
<wmeyer>
two variants, source type and destination type
<jyeo>
it's a one to one mapping but there's gonna be a lot of code
<wmeyer>
just pattern match one and create another instead of Obj.magic
<mrvn>
tobiasBora: it should be but it isn't.
<jyeo>
i guess i will stick to Obj.magic for now
<wmeyer>
possibly, but the code is straightforward
<Drup>
also, if Obj.magic work, Camlp4 should export the type equality ...
<mrvn>
tobiasBora: you need a functor for that
<jyeo>
Drup: report the type equality? can u rephrase that?
<Drup>
the fact that "Camlp4_import.Parsetree.structure_item = Parsetree.structure_item"
<Drup>
if Obj.magic works in this case, it means the types are strictly equivalent
<jyeo>
yeap
* Anarchos
is considering implementing hott
<Drup>
I don't even find Camlp4_import in ocaml sources, and the documentation is terribad, so don't know more.
* Drup
don't like camlp4.
<tobiasBora>
mrvn: Oh even by with this method... Thank you I'll try to have a look to functor then !
<Drup>
tobiasBora: did you benchmark "hardcoded" function against the high level one ?
Arsenik has quit [Quit: Quitte]
<tobiasBora>
Drup: Yes, functions aren't exactly the same but they are really similar
<Drup>
and what is the result ? :p
<tobiasBora>
And I know it's not a proper way to do it, but does a global variable containing the function to use could work ?
<Drup>
if it's the same type each time, yes.
<Drup>
but it sounds like a terrible idae
<Drup>
It would be the same as receiving the function as an argument, though?
<tobiasBora>
Drup: A really huge difference, my program is in exponential time, and with the first version I can't go after 13 in less than 40mn, while the second one allow me to go until 20 in less than 10 min.
<Drup>
Oh.
Yoric has joined #ocaml
<Drup>
is your code public ? I'm quite curious.
cdidd has quit [Read error: Operation timed out]
<tobiasBora>
I didn't put it on github because I will use it for my exams and I don't want to be accused of cheating but if you want I can send it to you by mail for example.
<Drup>
I feel like a baby seal is dying everytime someone send code by email.
avsm has joined #ocaml
cdidd has joined #ocaml
<tobiasBora>
Yes I know it's horrible, I'm just curious ^^ Why should it be the same as receiving the function as argument ? It doesn't copy each time the function isn't it ?
mcclurmc has joined #ocaml
<tobiasBora>
Hum... I didn't understand your expression ;-)
avsm has quit [Ping timeout: 264 seconds]
mcclurmc has quit [Ping timeout: 264 seconds]
mcclurmc has joined #ocaml
<mrvn>
tobiasBora: The problem is that arguments are not inlined and that makes a huge difference for small functions. More so if the function is a comparison that no longer gets optimized into a direct compare.
<mrvn>
tobiasBora: using currying to apply args doesn't change that.
mcclurmc has quit [Remote host closed the connection]
darkf has joined #ocaml
<tobiasBora>
mrvn: Even if I do something like let f1 = ....;; let f2 = ...; let current_func = ref f1;; and when I want to change the function : current_funcion := f2 ? If yes I don't understand why, references are like pointer isn't it ?
<mrvn>
tobiasBora: that's worse. How should the compiler inline the !current_function there? It's usualy impossible to proove the contents.
<mrvn>
tobiasBora: It would help with avoiding some polymorphic types though.
<wmeyer>
mrvn: what MLTon does is full text program analysis, to prove some corner cases
<wmeyer>
if your program does: let foo a f = let save = !current_func in current_func := bar; f (); current_func := save, then it's fine
<mrvn>
wmeyer: even then it might not be possible. You can turn it into a halting problem.
<wmeyer>
of course not in general case
<wmeyer>
but look at the idiomatic case above
<tobiasBora>
Uhm I see thank you... And functor allow to do it isn't it ?
nikki93 has quit [Remote host closed the connection]
<wmeyer>
functor does different tricks, but yes, in some way it's partial specialisation of module
<wmeyer>
every functor application is specializing the module versus another module
<Drup>
I don't think function application is going to allow more inlining
<Drup>
functor application*
<wmeyer>
in OCaml nope :)
<wmeyer>
oh
<wmeyer>
functor application
<mrvn>
Drup: the functor application would remove passing the helper functions as argument and use them directly. should inline them.
<wmeyer>
will not inline but will specialise the body of the module
<wmeyer>
OCaml does not do very well here
* Drup
invoke Pierre Chambart.
* wmeyer
summons OCamlPro
<Drup>
the first is included in the second/
mcclurmc has joined #ocaml
* wmeyer
time for some Haskell customisations
Yoric has quit [Ping timeout: 252 seconds]
testcocoon has quit [Quit: Coyote finally caught me]
testcocoon has joined #ocaml
tane has quit [Quit: Verlassend]
rand000 has quit [Ping timeout: 245 seconds]
Anarchos has quit [Quit: Vision[0.9.7-H-280704]: i've been blurred!]
avsm has joined #ocaml
Xenasis has joined #ocaml
<Xenasis>
Is there any way to get the type of argument a function takes? Where using it on ('a -> 'b) would obtain 'a?
<Xenasis>
*Where using it on a function with type signature 'a -> 'b
<bernardofpc>
sounds strange, you want something ('a -> 'b) -> 'a ?
<Drup>
Xenasis: in general, no.
<Drup>
Xenasis: depending of the specific use case, maybe we can cheat :)
<mrvn>
a type has no value representation in ocaml so you can't get it.
<Xenasis>
hmm
<Xenasis>
alright
<mrvn>
you can use GADTs to create witness type information
avsm has quit [Ping timeout: 245 seconds]
Yoric has joined #ocaml
<Xenasis>
hmm
<Xenasis>
yeah, I don't think GADTs are what I'm looking for
<Xenasis>
I guess I'll have to use another method, thanks anyway!
<mrvn>
or libsexp
<Drup>
Xenasis: what are you trying to achieve ?
<Xenasis>
one second, I miiight have thought of something
<Xenasis>
never mind, nope
<Xenasis>
basically
<Xenasis>
One of my assignments is creating ANY function with a specific type signature
<Xenasis>
We're given - type ('a, 'b) t_or = Left of 'a | Right of 'b;;
<Drup>
(before you do, mrvn, please don't give the solution)
<Xenasis>
Yeah, that'd be cheating
<Xenasis>
I'd rather understand it and get it myself than cheat
<Xenasis>
(This is why I asked for the method rather than the answer to my specific problem)
<Xenasis>
anyway -
<Xenasis>
val h : (('a -> 'b, 'a) t_or -> 'b) -> 'b
<Xenasis>
I need to get that
<adrien>
the line between guiding and giving the solution is small ;-)
<Xenasis>
so far I've managed to get -
<Xenasis>
val makeAbator : ('a -> 'b, 'c) t_or -> 'a -> 'b = <fun>
<Xenasis>
val h : ('a, 'a) t_or -> 'a = <fun>
<Xenasis>
Where makeAbator is -
<Xenasis>
let makeAbator (Left ab) a =
<Xenasis>
match (Left ab) with
<Xenasis>
| Left ab -> ab a
<Xenasis>
| Right a -> a;;
<Xenasis>
It's trickier than the last few questions, I'll give it that
<mrvn>
Xenasis: can that raise an exception?
<Xenasis>
It could, but we've not been taught about exceptions so that's not required
<Xenasis>
I'm not quite sure how to remove the second argument to the function and get the tuple to be ('a -> 'b, 'a)
<mrvn>
Xenasis: problem is: Say you get "Right of 'a" as argument how are supposed to convert that to a 'b?
<Xenasis>
hmmm
testcocoon has quit [Quit: Coyote finally caught me]
<Xenasis>
I guess that's what I'll have to do, at least
<mrvn>
00:13 < Xenasis> val h : (('a -> 'b, 'a) t_or -> 'b) -> 'b
<mrvn>
So h is a function taking type (('a -> 'b, 'a) t_or -> 'b) and returning type 'b
<Xenasis>
yeah
<mrvn>
let h fn = x
<Xenasis>
right
<mrvn>
that exercise doesn't make sense
<Xenasis>
I definitely know it's doable
<mrvn>
Are you sure you aren't leaving out something?
<Xenasis>
It's just a hard one :P
<Xenasis>
there are these -
<Xenasis>
type ('a, 'b) t_and = Both of ('a * 'b);;
<Xenasis>
type t_false ;;
<Xenasis>
but I'm not sure they're of any use
<mrvn>
you need some values
<Xenasis>
t_and is a tuple, t_false is... something
klltkr has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
testcocoon has joined #ocaml
<Xenasis>
I think you've set me off on a good path, at least
<mrvn>
you need a value of type ('a -> 'b, 'a) t_or so you can write: let h fn = fn x
<Xenasis>
I need to get 'a -> 'b from Right a
anderse has quit [Quit: anderse]
<maurer>
mrvn: this exercise is doable
<maurer>
mrvn: I have the solution
<maurer>
Honestly this is one of those weird problems that makes more sense if you think of constructing the program as constructing a proof term doing mental proof search >_>
<mrvn>
Xenasis: is the (('a -> 'b, 'a) t_or -> 'b) -> 'b supposed to be a function or the return value of a function?
<Xenasis>
that's supposed to be the type of the function
<Xenasis>
value I guess
<Xenasis>
val h : (('a -> 'b, 'a) t_or -> 'b) -> 'b
<maurer>
Xenasis: Have you done proof search before?
<Xenasis>
No
<Xenasis>
well
<Xenasis>
What do you mean by proof search?
<maurer>
A formal method for taking a set of inference rules and a conclusion and exhaustively but efficiently searching the set of possible proofs
<maurer>
You can do it informally too it turns out
<maurer>
but the short version is that there's only so many actions you can take while trying to construct this proof
<maurer>
and the tree isn't very big
<Xenasis>
Proof meaning of logic, or properties of programs?
<maurer>
logic
<maurer>
e.g.
<Xenasis>
ah
<maurer>
Your goal is to prove (('a -> 'b, 'a) t_or -> 'b) -> 'b
<maurer>
so the first thing that you do is you bind ('a -> 'b, 'a) t_or -> 'b) into your context and try to prove 'b
<maurer>
this corresponds to lambda binding ('a -> 'b, 'a) t_or -> 'b to a variable
<maurer>
etc.
<maurer>
you pretty soon see that there are like, two or three dead ends and one thing that works
<Xenasis>
this can be done without lambda expressions I think - we haven't been taught them
<maurer>
Xenasis: lambda expressions are just functions
<maurer>
and this cannot be done without two functions or a lambda expression
<Xenasis>
I thought it required >1 function
<Xenasis>
yeah
<maurer>
I'll probably have to go soon, but I gave mrvn the answer
<Xenasis>
Either way, I think learning a new way to search problems would be inefficient compared to just trying to work this out
<Xenasis>
thanks for your help anyway
avsm has joined #ocaml
<maurer>
Sorry, just figured there was a chance you had some background in type theory
<Xenasis>
Yeah, unfortunately we haven't, unless it has been disguised
<gasche>
this is the intuitionistic formulation of the excluded middle
<gasche>
not not (A or (not A))
<Xenasis>
huh?
<gasche>
the type you're given encode this proposition
<gasche>
your teacher certainly started from this to turn that into a programming question
<Xenasis>
I see
<gasche>
that may not help you much but it also explains maurer advice
<gasche>
but in any case, you can discover a solution just by trying a lot of things (as maurer pointed out, there are so many different things to try)
<gasche>
you're requested to write a term at a function type, so you can start with (fun f -> ...) and fill the dots
<maurer>
I mean, you know you have a ('a -> 'b, 'a) t_or -> 'b as input
<maurer>
what can you do with that?
<Xenasis>
try and formulate it?
<maurer>
No, that's the input
<maurer>
so you have one
<Xenasis>
right
<mrvn>
only thing you can do with that is call it
<maurer>
right
<Xenasis>
but I need to like
<maurer>
so the only way to move forwards is to construct a ('a -> 'b, 'a) t_or
<Xenasis>
Make the function look like that?
<maurer>
no
<Xenasis>
I'm not sure how to put that
<mrvn>
And you can only call it with Left or Right
<maurer>
you need to make a function that does (('a -> 'b, 'a) t_or -> 'b) -> 'b
<maurer>
You _have_ one that does ('a -> 'b, 'a) t_or -> 'b
<jle`>
is there some kind of definitive reference for debugging "this kind of expression is not allowed as the right-hand side of `let rec`"
<maurer>
and are trying to generate 'b
<gasche>
jle`: the user manual?
<Drup>
jle`: there is a very recent mail about that on the mailing list.
<gasche>
this has been asked on stackoverflow and the caml-list recently
<mrvn>
maurer: you are given a function that can generate a 'b, use it
<maurer>
mrvn: I assume you meant to address Xenasis ?
<mrvn>
yes
<mrvn>
Xenasis: ^^^
<jle`>
for starters i'm not even sure what "this kind" even refers to
<Xenasis>
o.o
<jle`>
gasche: i'll look into the user manual
<maurer>
jle`: Did you perhaps just try let rec f = fun x -> ?
<Drup>
jle`: this is also answered on the manual/mailing list
<maurer>
jle`: or something similar in pointfree style?
<Xenasis>
If it was as easy as that, I'd just do let h func = func - I have to actually make it match the input to tell OCaml what the input actually is
<Xenasis>
I don't /have/ the input
<gasche>
jle`: the basic rule is that none of the recursive definitions can be a function application
<mrvn>
Xenasis: let h func = func ???? you need to give it an argument.
<Xenasis>
exactly
<maurer>
Xenasis: OK, let's go a little slower
<maurer>
h = ?
<Xenasis>
name of the function
<maurer>
Well, this is a function, so let's get some things into our context, namely the left side of the arrow
<mrvn>
Xenasis: the type of which is a t_or. So you only have 2 options. Left or Right
<maurer>
no, ? here is the hole we're trying to fill in
<jle`>
gasche: it's sort of a complex mess of mutually recursive functions. i'll make all of them point free
<maurer>
h = fun f -> ?
<Xenasis>
I get that
<Xenasis>
oh
<gasche>
jle`: making them point-free is precisely what will tend to fail
<jle`>
just kidding, they're all point-free
<jle`>
ah.
<gasche>
can you eta-expand them?
<jle`>
not really
<maurer>
Now, we want to do something with f, because that is all we have that is relevant, but the only thing we can do is apply it
<jle`>
they are combinators
<maurer>
so we have
<gasche>
jle`: but do they return a function type?
<Xenasis>
right
<maurer>
h = fun f -> f ?
<mrvn>
Xenasis: let h func = func (Left ???) or let h func = func (Right ???).
<Xenasis>
well
<Xenasis>
we can't really write it like that
<jle`>
gasche: they return a function type wrapped in a data type
<Xenasis>
or
<Xenasis>
hmm
<gasche>
otherwise you can use lazyness, but it's a bit awkward
<jle`>
if i unwrap and rewrap then that defeats the whole purpose of the combinator library i am writing heh.
<mrvn>
Xenasis: What would be the types of ??? for the Left and Right case?
<maurer>
Xenasis: So, now your goal is to using your current context (you've got f, and that's it) write yourself something of type ('a -> 'b, 'a) t_or
<jle`>
you can turn on laziness? please tell me how haha
<maurer>
Xenasis: You've got the choices left and right, pick one
<Xenasis>
Yeah, and that's the bit I'm stuck on
<Xenasis>
I guess I need right just so left can by the same type (partially)
<Xenasis>
or accept the same type
<mrvn>
Xenasis: What would be the types of ??? for the Left and Right case?
<maurer>
So, which constructor are you picking? You're trying to construct a t_or, you gotta pick one
<Xenasis>
yeah
<Xenasis>
Right
<Xenasis>
as I said
<maurer>
OK, let's try that
<maurer>
h = fun f -> f (Right ?)
<Xenasis>
a
<mrvn>
have you got an 'a?
<Xenasis>
Right a (for ease)
<Xenasis>
I assume we do
<maurer>
...where?
<maurer>
I don't see one bound
<Xenasis>
well didn't we just do (Right a)
<Xenasis>
?
<gasche>
jle`: do you have a sample of compilable code?
<jle`>
gasche: i'm just going to add a depth parameter like i have before that decrements on each recursive call
<maurer>
Xenasis: where are you getting the a from?
<jle`>
gasche: i don't have anything too small that wouldn't waste your tiem going through all of it
<Xenasis>
Isn't this the input t_or?
<Xenasis>
like
<maurer>
no, the input is a function from t_ors to bs
<mrvn>
Xenasis: there is no input t_or
<Xenasis>
it was stated before (and I was pretty sure this was true beforehand) that we need two functions
<Xenasis>
right?
<maurer>
Xenasis: Only kind of, and you can ignore that since we're using lambdas
<maurer>
Just focus on what goes in the hole
<Xenasis>
if it's lambdas, then a
<maurer>
h = fun f -> f (Right ?)
<Xenasis>
lambda expressions don't need types, I think
<maurer>
Show me where "a" is bound
<Xenasis>
# (fun x -> x);;
<Xenasis>
- : 'a -> 'a = <fun>
<maurer>
that's not the same a
<Xenasis>
right
<Xenasis>
but it doesn't need to be the same 'a in our function
<maurer>
and Right wants 'a, not 'a -> 'a
<mrvn>
that isn't even type 'a,
<Xenasis>
I know a != 'a
<Xenasis>
but it's easy to call the thing we want to be type 'a a, right?
<maurer>
Xenasis: sure, but the way you would write that would be
<mrvn>
Xenasis: no. you don't have a magic hat to pull an a out of.
<maurer>
h = fun f -> f (Right (fun a -> ?))
<maurer>
And when you do that, there is no way for that to typecheck
<maurer>
because no matter what you put in the ?, it will still be a function type when you pass it to Right
<Xenasis>
Can we do this without lambda expressions? :/
<Xenasis>
like
<mrvn>
let h f = f (Right (fun a -> ?))
<mrvn>
still just as wrong
<Xenasis>
I don't really know much about them
<maurer>
OK, we can do it without lambdas
<Xenasis>
and we don't need them
<maurer>
So then we are at
<Xenasis>
thanks
<maurer>
let h f = f (Right ?)
<maurer>
what do you want to put in the ?
<mrvn>
and what type is the ? ?
<Xenasis>
We'd ideally want an a, but we can't have that so we need another function with Right a as an input I think?
<mrvn>
no, there is no a
<Xenasis>
(Right a) as the input
<Xenasis>
I mean
<mrvn>
and a is not a type
<maurer>
Xenasis: What would the type of this other function be?
<Xenasis>
I know that
<Xenasis>
but a is an easy way to show 'a
<mrvn>
Xenasis: think about the type first
<Xenasis>
like ab would be an easy way to show 'a -> 'b
<maurer>
... you can't show 'a -> 'b though
<Xenasis>
this was just an example
<Xenasis>
to show that I don't think that calling something a makes it 'a
<maurer>
OK, you wnat to call the other function a, that's fine, but what do you want it's type to be?
<maurer>
And if the answer is 'a, why do you think it should be a function?
<Xenasis>
I don't want to call the other function a
<Xenasis>
I want the input to be (Right a)
<Xenasis>
the function would be something like
<mrvn>
Xenasis: let h f = f (Right ?), what type does the ? have?
<Xenasis>
We cannot do that without lambda expressions
<Xenasis>
right?
<Xenasis>
we need two functions
<maurer>
Xenasis: you do not yet have any need to introduce a function
<maurer>
in order to fill in the blank here, you are attempting to, using only f : ('a -> 'b, 'a) t_or -> b, produce 'a
<maurer>
Do you think you can do this?
<maurer>
If so, how?
<Xenasis>
in which case I do not know what the ? can be in (Right ?)
<Xenasis>
There's no input we can give it
<maurer>
OK, so we don't see a way to proceed here
<mrvn>
Xenasis: bingo
<maurer>
So why don't we try the other branch
<maurer>
let h f = f (Left ?)
<Xenasis>
THIS is why I was trying to make another function
<Xenasis>
:/
<mrvn>
Xenasis: Right is a dead end. It doesn't work.
<maurer>
What is the type of the ? here?
<Xenasis>
I'd imagine it'd be f
<mrvn>
Xenasis: f is not a type
<Xenasis>
f is a function
<mrvn>
f is a value
<Xenasis>
right
<Xenasis>
so it could be (for example) ab
<maurer>
What is the type of our hole
<mrvn>
ab is not a type
<Xenasis>
'a -> 'b if you're being pernickety
<maurer>
OK, 'a -> 'b is the type of the hole
<Xenasis>
I was just shortening things for ease
<maurer>
Notably _not_ unifiable with f
<maurer>
So, we ask ourselves "How do we make a function?"
<mrvn>
Xenasis: do you have some value of type 'a -> 'b or could you (maybe) create one?
<maurer>
The answer is usually basically one of "We already have one"
<maurer>
or "We write one"
<maurer>
Do we have one?
<Xenasis>
I can't write something of 'a -> 'b
<Xenasis>
I think I could assume it exists though
<Xenasis>
in some function
<Xenasis>
hell, I've done that so far
<mrvn>
Xenasis: lets call it "g"
<mrvn>
let h f = f (Left g)
<mrvn>
let g ....
<mrvn>
How should g look like?
<Xenasis>
I'm not quite sure, my old approach was largely dissimilar from this one
<Xenasis>
perhaps
<Xenasis>
hmm
<mrvn>
type 'a -> 'b. so it must be a function
<Xenasis>
let g a = (somehow obtain b)?
<Xenasis>
I'm not sure I can write a function that does simply a' -> 'b on its own
<Xenasis>
I could have that in a list of things, but that's of no use
<mrvn>
Xenasis: you can't. but what do you have as values now?
<Xenasis>
a?
<Xenasis>
wel
<Xenasis>
*well
<Xenasis>
h, f, g, a
<mrvn>
a is type 'a. doesn't help. what else?
<Drup>
you don't have g et h *yet*
<Xenasis>
h, f, g
<Xenasis>
oh
<Xenasis>
so f then
<Drup>
indeed
<mrvn>
ack
<Drup>
look at the type again, and see if you can do something of type 'a -> 'b with it
<mrvn>
let g a = f ?
<jle`>
gasche: is this common, to add that depth parameter in my mutually recursive functions so they don't let rec forever?
<mrvn>
Left or Right?
<Xenasis>
I'm not sure if I can do something with just f
<jle`>
gasche: they create a function that parses a possibly infinitely recursive grammar
<maurer>
Xenasis: You have a 'a, and you are looking to construct an argument to f, can you see a way to do this?
<Xenasis>
I can get stuff like
<Xenasis>
# let f fun1 value = fun1 value;;
<Xenasis>
val f : ('a -> 'b) -> 'a -> 'b = <fun>
<mrvn>
Xenasis: you need to fill in the "?"
<Xenasis>
but that's two things
<Xenasis>
Yeah, no, I can't construct (('a -> 'b, 'a) t_or -> 'b) -> 'b inside f :/
osa1 has quit [Ping timeout: 240 seconds]
<maurer>
f : ('a -> 'b, 'a) t_or -> 'b
<maurer>
a : 'a
<maurer>
Please tell me you can see a way to use these two things together
<Xenasis>
oh, so you're letting me use a?
<gasche>
jle`: I think the best thing here would be to compromise with your combinator interface and a way to expose that evaluation will be delayed
<maurer>
...you bound it in the function
<gasche>
something as simple as
<mrvn>
Xenasis: you bound an "a" so you can now use it
<Xenasis>
<mrvn> a is type 'a. doesn't help. what else?
<Xenasis>
:/
<Xenasis>
alright fine
<Xenasis>
I have a
<Xenasis>
I guess we want
<mrvn>
Xenasis: that was before you got "let g a = f ..."
<Xenasis>
well, I didn't do = f
<Xenasis>
but I roughly got that
<Xenasis>
<Xenasis> let g a = (somehow obtain b)?
<Xenasis>
anyway
<Xenasis>
I guess I want
<Xenasis>
let f a = match (Left a) with?
<gasche>
something like
<gasche>
delay : 'a t Lazy.t -> 'a t
<mrvn>
Xenasis: no. f is an argument given by the user. you don't have to create one.
<gasche>
then you can use lazyness as in
<gasche>
let rec x1 = lazy (foo bar (delay x2)) and x2 = lazy (blah (delay x1) blah)
<gasche>
in some cases you don't need this "delay" and can simply use Lazy.force instead
<gasche>
but if you're really building terms as nested function applications, in a call-by-value language all arguments will be forced
<gasche>
(I mean obviously something like let rec x = lazy (1 + Lazy.force x) is not going to work
<jle`>
hm thanks
<jle`>
i didn't realize when i was starting out that how much i relized on laziness before
rand000 has joined #ocaml
<gasche>
it's true that some things with combinator libraries are more convenient with lazyness in the right places
<gasche>
that said I personally prefer to control evaluation order and see where lazyness occurs explicitly
<Xenasis>
so do I need to do <Xenasis> let f a = match (Left a) with? ?
<Xenasis>
in some description?
<gasche>
with combinators, I also like to build fixpoint explicitly (val fix : ('a -> 'a t) -> 'a t) rather than building infinite terms with a recursive definition
<mrvn>
Xenasis: f is given and has type ('a -> 'b, 'a) t_or -> 'b
<Drup>
Xenasis: "match (Left a) with -> " is pretty meaningless
<Xenasis>
ah, alright
<Xenasis>
thanks Drup
<Xenasis>
hmm
<Xenasis>
I'm not quite sure what to /do/ with (Left a) then
<jle`>
gasche: thanks, i'll keep that in mind. just have to learn to do things slightly differently
<mrvn>
Xenasis: you were at "let g a = ..." and had the idea to use "f" ==> "let g a = f ....". So how do you you continue?
<gasche>
Xenasis: the function you're looking for, with type (... t_or -> 'b) -> 'b, is of the form (fun f -> f (Left ???)) or (fun f -> f (Right ???))
<Xenasis>
I'm not quite sure - I didn't propose f
<mrvn>
What choise are there for the argument for f?
<mrvn>
01:01 < Xenasis> so f then
<Drup>
gasche: we get pass this point a few time ago ;)
<mrvn>
you did
<Xenasis>
I'm not sure, I'm not good at lambda expressions
<Xenasis>
We've not been taught them
<mrvn>
there is no lambda in let g a = f ....
<Xenasis>
<gasche> Xenasis: the function you're looking for, with type (... t_or -> 'b) -> 'b, is of the form (fun f -> f (Left ???)) or (fun f -> f (Right ???))
<Xenasis>
" (fun f -> f (Left ???)) or (fun f -> f (Right ???))"
<Xenasis>
fun = lambda expression
<mrvn>
Xenasis: ignore that
<Xenasis>
Yeah, I'm not sure what to do with (Left a) if I'm not matching it
<Drup>
well, you still have a function
<mrvn>
Xenasis: where do you see a (Left a) in let g a = f ....?
<Xenasis>
Exactly, we need to make one
<Xenasis>
Didn't we decide on Left a?
<mrvn>
so you want to use Left next? let g a = f (Left ?)
<mrvn>
what type does ? have?
<Xenasis>
I didn't say "next"
<Xenasis>
I'm not sure, but we DO need to create a t_or
<Xenasis>
and we need the word Left or Right to do that
<mrvn>
indeed.
<mrvn>
and you decided to try Left
<Xenasis>
right, because Right was wrong
<mrvn>
in h Right was wrong. doesn't mean anything
<Xenasis>
So obviously, as I said, (Left a) works
<mrvn>
let g a = f (Left ?) what type does ? have?
<Xenasis>
It depends what we do with it
<Xenasis>
but it's 'something
<mrvn>
not realy
<mrvn>
f : ('a -> 'b, 'a) t_or -> 'b
<mrvn>
That gives you the type for the ?
<Xenasis>
so it's 'a -> 'b, right?
<mrvn>
Xenasis: and what type does "a" have?
<Xenasis>
I'm not sure
<mrvn>
01:04 < maurer> a : 'a
<Xenasis>
I think we originally gave it 'a, but we want 'a -> 'b
<Xenasis>
the problem I got with using left though was I can't get the right side to be 'a
<Xenasis>
I think we need to use Right :/
<mrvn>
Xenasis: So (Left a) can't work, the types don't fit.
<Xenasis>
...so we /do/ need to use RIght :/
<mrvn>
Xenasis: lets try that: let g a = f (Right ?)
<mrvn>
What type does ? have now?
<Xenasis>
'a
<mrvn>
and oh wonder we do have "a: 'a".
<mrvn>
Xenasis: so how do h and g now look?
klltkr has joined #ocaml
<Xenasis>
I'm not quite sure yet
<Xenasis>
alright
<Xenasis>
so g = 'a -> (('b, 'a) t_or -> 'c) -> 'c = <fun>
<Xenasis>
and f is (('a -> (('b, 'a) t_or -> 'c) -> 'c) -> 'd) -> 'd = <fun>
<mrvn>
I have no idea how you get that. I ment what the source for h and g looks now
<Xenasis>
ahhh
<Xenasis>
okay
<Xenasis>
g would be -
<Xenasis>
let g a f = f (Right a);;
<Xenasis>
and I guess h is -
<Xenasis>
let h f = f g;;
<Xenasis>
?
<mrvn>
Last we had was: 00:58 <@mrvn> let h f = f (Left g)
<Xenasis>
ahh
<Xenasis>
alright, that, then
<Xenasis>
let h f = f (Left g)
<mrvn>
But that was under the assumption that g would be 'a - 'b
<mrvn>
Now g needs the f too.
<mrvn>
Xenasis: lets swap the "a" and "f" in g: let g f a = f (Right a)
<Xenasis>
alright
<mrvn>
Xenasis: val g : (('a, 'b) t_or -> 'c) -> 'b -> 'c = <fun>