<Leonidas>
but why doesn't it complain about the lack of 'let rec'?
<Leonidas>
it is a recursive function...
<Camarade_Tux>
are you in the toplevel?
<Leonidas>
yep, including code via #use
<olegfink>
okay, I think I have the stupidest question I have ever asked here: if I want to generate some LLVM assembly with OCaml, should I use ocaml llvm bindings or hlvm? Or hlvm is something completely different?
<Camarade_Tux>
you probably have a previous definition of your function
<Camarade_Tux>
Leonidas: try closing and reopening the toplevel ;-)
<Leonidas>
Camarade_Tux: true. Indeed, that was it.
<Leonidas>
can I have polymorphic records? I have this ware-record and I would like to have the type of price parametrized.
ygrek has joined #ocaml
<Leonidas>
ok, got it working.
<Leonidas>
No idea what went wrong previously
Pimm has joined #ocaml
* mrvn
wants prefix types.
<flux>
what are those?
<mrvn>
type a1 = { x : int } let get a = a.x type a2 = { a1 with y : int } let _ = get { x = 1; y = 2 } ikind of things.
<mrvn>
a1 is a prefix of a2.
<flux>
well, you've got the source :)
<Leonidas>
can I put multiple clauses into a when?
<flux>
mrvn, your syntax suggestino seems reasonable. however, how would that interact with type inference?
<flux>
leonidas, it's one boolean expression, it can be composed of many expressions
<mrvn>
flux: We already have [< ], [> ] and < .. > types.
<flux>
mrvn, but they are sort of structural types
<Leonidas>
flux: oh, right (shame on me for *that* question)
<mrvn>
a1 is < x : int >, a2 is < x: int; y : int > an get takes a < x: int; ..>
<mrvn>
except with records instead of classes.
<mrvn>
I would think as type it would be { x : int; .. }
<flux>
mrvn, wouldn't that completely change the way records are handled..
<mrvn>
type a1 = Foo type a2 = Foo | Bar could use [</[> syntax like private types.
<mrvn>
flux: How are records handled? acess to members is by offset. That remains.
<flux>
mrvn, but the record types would change
<mrvn>
flux: and copying like { a with x = 17; } can copy the memory representation of a whatever its length is.
<flux>
mrvn, for example the types of let foo a = a.x and let foo a = a.y
<mrvn>
flux: I would suggest that they default to strict types like now and one can annotate when they should accept prefixes.
<mrvn>
let foo (a : { x:int; .. }) = a.x
<mrvn>
maybe { a with .. } so one doesn't have to retype the type.
<flux>
definitely with the 'with' if that kind of prefix-limitation is there, otherwise the syntax would allow all kinds of things that are not supported?
<mrvn>
No. Don't think so. The "with" would just be saving keystrokes.
<mrvn>
foo should accept anything that has an x:int as first element of its record even if it is not derived from a I think.
<flux>
well, let foo (a : {x : int; y:int; ..}) = .. let bar (a : {x: int; z:int; ..}) = .. let baz (a : {x: int; z:int; ..}) = .. wouldn't these all accept type a = {a : int; b : int; z:int; }?
<flux>
well, I guess not if the name and order of fields is signnificant, which I believe you're suggesting
<flux>
however it sounds more fragile
<flux>
if you need to state the order of the fields all over the code
<mrvn>
The order and type of fields is relevant. The name can be relevant or not.
<mrvn>
flux: yeah, the "with" syntax is to void repeating the type all over. WOuld make it error prone and hard to change the type.
<mrvn>
The a in { a with ...} is sort of like a class type.
<flux>
perhaps you should make a writeup of the idea with all the cases covered
<flux>
basically it would be a limited form (for performance reasons) of structural records ala SML, right?
<mrvn>
don't know sml
<mrvn>
It would be a limited form of ocaml classes with performance benefits.
<mrvn>
and less space required
<flux>
neither do I, but someone here advocated its features every now and then :)
<mrvn>
For the implementation I think only the {a with x = 17; } code generation would have to be changed. All the rest is just type inference.
<flux>
hmm.. why would it be changed?
<mrvn>
flux: I thing is allocates a new block the size of the resulting type and then copies the data. WIth { a with .. } is has to allocate memory as large as the input type at runtime.
<mrvn>
It doesn't know the size at compile time.
<flux>
hm, right
<mrvn>
Would make it slower than not prefixed types but still a lot faster than objects.
<flux>
I might thing that the other advantage of having the capability to share record field names with semantically similar records would even be greater.. not everyone are as performance-obsessed as you :)
<mrvn>
flux: You have that in classes. They are just slow and give ugly errors.
<flux>
you don't have pattern matching and other nice stuff of records with classes
<flux>
well, there's a syntax extension for pattern matching, haven't tried it..
<mrvn>
and I think you can't "match a with { x = 17 } ->" with classes, right?
<mrvn>
hehe. :)
<mrvn>
LAG
<mrvn>
flux: If you have type vec2 = { x:float; y:float } type vec3 = { vec2 with z:float } then the speed difference to classes is astronomical.
<flux>
maybe that 'with'-kind would be useful even without more complicated typing. conside that vec2/vec3 example. you could have functions like: let vec3_of_vec2 x = { (type vec2) a with z = x } and let vec2_of_vec3 x = (x : vec3 :> vec2)
<flux>
no new types. you wouldn't have the polymorphicity you want, though.
<mrvn>
flux: yeah. vectors are a bad example anyway. YOu don't want to call Vec2.add on a Vec3.t.
<mrvn>
flux: Currently I have a vec2_of_vec3 with Obj.magic
ygrek has quit [Remote closed the connection]
<mrvn>
A vec3_of_vec2 is dangerous though.
<Leonidas>
I have a question on the type system and I suppose the key to the question are the option types, but i don't yet see 'how':
<Leonidas>
I have a function, max which returns the maximum object (for some definition of maximum) of a list. But what if the lsit is empty?
<Leonidas>
I could return None, but then the type of the [x] -> x case is incorrect
<Leonidas>
as x is not an option type
<tiz_>
[x] -> Some x
<Leonidas>
tiz_: yeah, I figured that out, but then I get into problems in the case with two elements:
<Leonidas>
how do I compare two option types?
<tiz_>
Use pattern matching to get the actual values out of the option types and compare them.
aklt has joined #ocaml
<Leonidas>
hmm, will try.
<tiz_>
This isn't perfect (not tail recursive) but it's the simplest version of what you want and will show the principle:
<Leonidas>
tiz_: oh, nice page. Haven't seen that one yet. Thanks :)
<Leonidas>
is there a way to unify calculation with numbers like for example the max function does?
<flux>
you can get sort of the same effect with objects, but it means you also need to wrap each number into one before proceeding
<Leonidas>
for example, if I want to multiply x with y, with both having type 'a
nagnatron has joined #ocaml
<flux>
the problem is that you cannot multiply everything
<flux>
like lists or sockets
<Leonidas>
oh, that sounds like too much of a hassle for what I am trying to do.
<thelema>
since ocaml has a polymorphic compare, you can compare anything, though.
<flux>
..except functions
<mrvn>
Leonidas: I would write 2 functions:
<mrvn>
1) let rec max_or_default def = function [] -> def | x::xs -> max_or_default (max x def) xs
<mrvn>
2) let max = function [] -> None (* or raise Empty *) | x::xs -> max_or_default x xs
<flux>
pft, how often is max_or_default useful? alternatively you could use ExtLib's Option-module to extract values with default values out of an option type..
<mrvn>
flux: every time you call max. :)
<mrvn>
let max x = let rec max_or_default ... in ... works too.
<mrvn>
I believe having a helper function without option type will be much better for the compiler.
<flux>
..if performance is everything :)
<mrvn>
easier to read too.
<flux>
max_or_default a b, which one is the default?
<mrvn>
flux: It is a helper function. YOu probably would not put that into the mli file.
<Jedai>
Leonidas: If you want something like that (a multiplication function that works for several types for which it makes sense) you may investigate the typeclasses from Haskell
<Jedai>
Leonidas: Or you could try the OO part of OCaml, though that doesn't bring the same kind of facilities
<Leonidas>
Jedai: the point is, I am doing my homework and while I would like to have an awesome solution, that works on everything, I don't think that it is a good idea to go into typeclasses.
ikaros has joined #ocaml
<flux>
leonidas, well, you could functorize your solution
<Jedai>
Leonidas: Well probably not in this case
<flux>
leonidas, but I'm guessing you haven't covered functors just quite yet..
<Leonidas>
flux: no, not yet. First homework in Ocaml. So far it has been quite fun :)
<mrvn>
Leonidas: YOu can define a class arithmetical with methods add, sub, mul, div, ... and then derive classes for int, float, bigint, ... from that. But that is more an execise to show what can be done with OO than real use case.
<Leonidas>
mrvn: yeah, sounds as verbose as the java biginteger-stuff which is really tedious to use.
<mrvn>
Leonidas: you can overload the + operator to use the class.
<mrvn>
let ( + ) = Arithmeical.plus
<Leonidas>
Oh, did I already mention that I am seriously impressed with the support I got from this channel? Totally awesome :)
<Leonidas>
mrvn: oh, I see. Ok, that would be a possibility.
<flux>
mrvn, I wouldn't call it overloading, but redefining..
<Leonidas>
but feels a bit out of scope.
<mrvn>
shadowing is the right word I believe
willb1 has joined #ocaml
<Leonidas>
I guess a take a few minutes break for things to settle in my mind...
Modius_ has quit ["I'm big in Japan"]
willb1 has left #ocaml []
willb1 has joined #ocaml
willb1 has quit [Client Quit]
tmaedaZ0 has quit [Read error: 110 (Connection timed out)]
Yoric has quit []
Yoric has joined #ocaml
ygrek has joined #ocaml
Dodek_ has joined #ocaml
seanmcl has joined #ocaml
Dodek_ has quit [Read error: 104 (Connection reset by peer)]
<Leonidas>
I still don't get when to use ;;. Sometimes it works without, sometimes I run into problems if I leave it out. What is the #ocaml folks recommendation?
<mattiase>
Leonidas: Basically, you need it if the next top-level thingy doesn't start with a keyword. You can always make this happen by doing let _ = f() instead of just f().
<flux>
leonidas, ;; separates processing units
<flux>
leonidas, a processing unit is EITHER a list of statements OR an expression
<mattiase>
Leonidas: But it doesn't hurt to add it wherever you see fit.
<flux>
leonidas, does this make sense?
<flux>
of course, you also need ;; whenever you want to process some statements (or expressions)..
<flux>
leonidas, I never use ;; unless it's on the toplevel
<flux>
leonidas, however, as a newbie it might be useful, because somtimes ;; can give you better location for an error
seanmcl has quit []
seanmcl has joined #ocaml
<mattiase>
What we really need is an environment that separates Enter from Return, so there.
Pimm has quit [Read error: 110 (Connection timed out)]
<mrvn>
flux: or give starnge errors
<mrvn>
mattiase: the revised syntax obsoletes the ;; completly I think
<Leonidas>
flux: it doesn't work unless I add ;; at the end of line 46.
<Leonidas>
mrvn: revised syntax?
<mattiase>
mrvn: The only problem with the revised syntax is that it doesn't go far enough. And, that nobody uses it.
<mrvn>
Leonidas: from camlp4
<Leonidas>
as you see, the code in my paste is either using ;; or not. And it seems to work, but I don't know exactly why.
<mrvn>
mattiase: I think it fixes some thing but I also think it is a verry bad idea to have 2 syntaxes
<Camarade_Tux>
I'm looking for a way to easily use RPC functions, like being able to call "M.f 42" and "Remote_M.f 42" as easily, currently ocamlnet's rpc needs that you take care of the marshaling part (and that you open connections), has anyone something like that or heard of something like that?
<Leonidas>
mrvn: ah, ok.
<flux>
leonidas, line 44: statement line 49: expression
eni_ is now known as albacker
<flux>
leonidas, thus it doesn't match neither the rule "list of statements" nor "an expression"
<mattiase>
mrvn: Completely agreed, but it is also clear that the standard syntax has problems.
<Leonidas>
flux: ah, so I can put as many statements as I want and only put one ;; at the end?
<flux>
leonidas, yes
<flux>
leonidas, and you can make a statement of any expression: convert <expr> into let _ = <expr>
<Leonidas>
but at the end, it needs at least one ;;?
<mrvn>
Leonidas: ;; only tels the toplevel "start executing all the input NOW"
<flux>
leonidas, no, if it's a file you are compiling
<flux>
leonidas, yes if you paste it to toplevel and want to process it..
<flux>
but I need to go now, happy coding
<Leonidas>
I mostly use #use
<Leonidas>
flux: thanks.
<mrvn>
Leonidas: Simple rule: Ever only type ;; in the toplevel. :)
<mrvn>
and who cares about rounding in an exercise?
<mrvn>
Leonidas: let total_cost (w, n) = w.preis * n
<mrvn>
Leonidas: maxlist and maxlist_tail should be unified.
delsvr has joined #ocaml
<orbitz>
a lot of people are calling go's type system liek ocamls in terms of structural polymorphism, but I don't see it, you still have to state the name of the itnerface you want which sounds more like a weaker haskell, anyone looked at Go?
<mattiase>
Go looks very much like the perfect dream language of 1973. No, I don't find the comparison to ocaml really valid either.
dmentre has quit ["Leaving."]
seanmcl has quit []
Nepomuk has joined #ocaml
seanmcl has joined #ocaml
<orbitz>
mattiase: specifically the comparison is in typing
<csmrfx>
F# more appr
<orbitz>
they say the type system is liek duck typing
<orbitz>
but i totally disagree
<orbitz>
since you still need the name of the interface
<thelema>
it's much more like duck typing than the C++/Java world has seen before.
<mattiase>
orbitz: There are plenty of languages allowing polymorphic method invocation on objects of otherwise unrelated types (Java, Objective-C, etc)
ezrakilty has quit ["Puh-peace!"]
<orbitz>
what i'm saying though is in ocaml you just use yoru object calling the emthods you want, and the type becomes a union of those mthods, in Go you still are restricted to names of interfaces taht are collectiosn of methods
<mattiase>
orbitz: indeed.
<orbitz>
i wonder if you can specify a type is of multiple interfaces in go like in haskell though
<mfp>
orbitz: you could also argue that it's structural polymorphism without inference
<orbitz>
hrm perhaps
<csmrfx>
Whats there like duck typing in go? isnt it just lazy init of types
<csmrfx>
cough type
<csmrfx>
hm, nm
rwmjones_lptp has joined #ocaml
tmaeda is now known as tmaedaZ
<csmrfx>
Any Ocaml video lectures. Stanford had some for scheme, cpp and python, that was great. I wish Ocaml had some too
smimou has joined #ocaml
seanmcl has quit []
zhijie has joined #ocaml
ikaros_ has joined #ocaml
ikaros has quit [Read error: 145 (Connection timed out)]
Pimm has quit [Read error: 110 (Connection timed out)]
<Leonidas>
mrvn: maxlist and maxlist_tail shouldnt be unified, the assignment asks explicitly for both :)
<Leonidas>
mrvn: haven't used hashtables in ocaml yet. The assignment asks for records, so they get records.
<Leonidas>
but total_cost is nice, should have done it your way
<thelema>
Leonidas: a hashtbl would be more appropriate than the list for holding all the items.
<thelema>
items in the cart
<Leonidas>
thelema: yep, you're right. That would also take care of duplicate keys.
<thelema>
exactly.
<Leonidas>
thelema: I guess the people who make our assignments don't value common sense very much...
<Leonidas>
or maybe they think that a list might be easier to get started with.
<thelema>
simplicity often wins over proper design.
<Leonidas>
exactly
Amorphous has quit [Read error: 110 (Connection timed out)]
Pimm has quit [Read error: 110 (Connection timed out)]
Amorphous has joined #ocaml
<mrvn>
thelema: howcan that be? Simplicity often is the proper design.
<mrvn>
Leonidas: You can habe both but one should call the other.
<mrvn>
Leonidas: or both call a third that doesn't use options.
<thelema>
mrvn: simplicity is usually easier to implement, and gets the job done in many cases.
<mrvn>
Leonidas: Was the option type for maxlist_tail required? Because it suspiciously looks like you were to implement maxlist_tail without option and then extend that in maxlist to handles empty lists as well.
<mrvn>
Time for a good book and then bed.
alp_ has quit [Client Quit]
Alpounet has joined #ocaml
tarbo2 has quit [Client Quit]
tarbo2 has joined #ocaml
_andre has quit ["Lost terminal"]
onigiri has joined #ocaml
ttamttam has joined #ocaml
cognacc has joined #ocaml
jcaose_ has joined #ocaml
jcaose has quit [Read error: 60 (Operation timed out)]
albacker is now known as edon
edon has quit [Remote closed the connection]
albacker has joined #ocaml
ygrek has quit [Remote closed the connection]
jcaose_ has quit [Read error: 54 (Connection reset by peer)]