<def-lkb>
Yann is busy at the moment, and there are a lot of features to discuss so it will probably take a long time.
<def-lkb>
In particular, I am worried a bit by the API of some features, e.g for querying state or the need of two layers of wrapping/unwrapping for each step which may impede performance
<Drup>
knz: please indent this first math for ml correctly
<Drup>
this hurt my eyes
<Drup>
match*
<knz>
how do you mean?
<knz>
I think my example highlights the problem very well :)
<Drup>
highlighting a problem by deliberately screwing the indentation that any correct indentation engine would do is not a good way to show an issue
<smondet>
the problem being that you don't use a decent text editor?
<Drup>
(oh, and you forget to mention that haskell indentation engine are complete crap too)
<knz>
smondet: the problem is needing begin+end for something that indent should solve
<knz>
but yeah
<Drup>
also
<Drup>
I would argue that indentation based languages is a matter of taste
<Drup>
certainly not a killer feature
<Drup>
(I don't like it, for example)
<knz>
there's a lot to argue when comparing stuff
<knz>
anyway
<knz>
I know people who would also argue that ad-hoc polymorphism is a matter of taste
<companion_cube>
typeclasses are definitely an asset
<knz>
of course all this is a matter of taste, since ocaml is not so bad after all that many people use it
<Drup>
knz: well, not the same proportion of people :)
<knz>
heh :)
<knz>
well, I know a number of c++ and java programmers...
ontologiae has joined #ocaml
<Drup>
knz: for show and stuff, you should add the typeclass parametrisation
<knz>
why?
<Drup>
"show : a -> String" is far too much magic without "Show a =>" before
<knz>
ah
<knz>
"too much magic" is a good argument
<knz>
I'll fix it
yacks has joined #ocaml
avsm has joined #ocaml
pango has quit [Ping timeout: 265 seconds]
avsm has quit [Client Quit]
<def-lkb>
ad-hoc polymorphism via typeclasses is strictly more expressive, indentation is really a matter of taste
<Drup>
knz: so, I've done exactly this trip 6 month ago
avsm has joined #ocaml
<knz>
def-lkb: you seem to equate "more expressive" = "better, would like to use"
<knz>
I think that is also a matter of taste
<Drup>
so I can tell what exactly bugged me
<Drup>
when I did the transition
<knz>
please do?
divyanshu has quit [Quit: Computer has gone to sleep.]
<Drup>
and those stuff are not express well enough in your post
<Drup>
1) implicit recursivity, this is a big one
divyanshu has joined #ocaml
<companion_cube>
typeclasses write some code automatically
<def-lkb>
knz: usability of implementation and wether it's useful or not is matter a taste
<bernardofpc>
knz: I'd not argue that identing is a killer feature, otherwise ASM & FORTRAN would be better than C
<companion_cube>
asm, really?
<def-lkb>
knz: but gain in expressivity is objective
<Drup>
because you can't really do the usually idiom "let a = foo in let a = f a in ..." when f is a "modifying a little bit" function
<knz>
bernardofpc: I know enough people that can argue strongly that mandatory indentation is *the* killer feature that made them migrate away from perl/php to python. So I won't go down this lane today.
<knz>
Drup: right
<Drup>
2) the module system is complete crap and the module namespace is not strongly enforced (you can add the module Foo.Bar when Foo.Baz is already in the scope)
<Drup>
and also, no local open
<knz>
Drup: that's something I was arguing this morning with someone else; my opinion is that what you call "the usual idiom" does not occur that often, or does it?
<knz>
about modules, well
<knz>
yes it's crap
<bernardofpc>
more flexibility on operator and function names -> again, this is not a killer to my taste, this is not like "higher-order functions" or "first-class modules"
<Drup>
knz: well, it was an usual idiom for me.
divyanshu has quit [Client Quit]
<Drup>
knz: and I think I'm a quite "normal" ocaml programmer
<bernardofpc>
a killer is being able to express something you cannot in the other language without too much effort
venk has quit [Ping timeout: 240 seconds]
<bernardofpc>
for example, chosing the precedence is indeed a good thing
<knz>
ok
<Drup>
to be more precise about "not strongly enforce"
<Drup>
a package can defined a module Foo and *another package* ca define the module Foo.Bar
<Drup>
which is completly alien for an ocaml programmer :D
<knz>
hum
<Drup>
other that
<knz>
it is not too surprising in this era of domain names
<Drup>
well, it was for me
<Drup>
I would add a "quick guide to ghc extensions"
<knz>
I think more and more people are comfortable with the idea that x and x.y may have different responsibilities
<knz>
ok
<Drup>
because some of them are really useful
<knz>
oh?
<bernardofpc>
as for the readable type interface, I don'k know Haskell enought, but the .mli serve a different purpose
<knz>
Drup: even for the beginner?
<Drup>
we are talking about ocaml programmers, not Java ones
<knz>
right
<knz>
well I already pointed -XGADTs
<knz>
which others did you have in mind?
<Drup>
the landscape of GHC extensions is a bit wild
<Drup>
Deriving Monad, Traversable and Functor
<Drup>
talk about the usage of newtypes
<Drup>
( ^ this is really a killer feature)
<Drup>
you don't talk about typeclasses all that much
<knz>
well
<Drup>
you could give the example "how to replace the Map functor by the Ord typeclass"
<Drup>
it's a good example of how to do stuff
<knz>
ah
<knz>
yes you are right; yet I found that the haskell tutorial was already explaining type classes very well
<knz>
I am not sure I can do better
<knz>
although... maybe an example would not hurt
<knz>
otherwise
<Drup>
well, when I started haskell
<knz>
you mention newtypes
<knz>
what's about it?
<jpdeplaix`>
knz: I your example for « Functional goodies », (@.) should be (%) instead
<knz>
jpdeplaix`: why?
<Drup>
I knew what typeclasses where, I knew some example of it
<Drup>
but I didn't realize how you could use them to replace ML's functors
<Drup>
to enforce non-unification between typealiases
<companion_cube>
wouldn't %> be even more useful?
<Drup>
to do the same in Ocaml, you need to go though a private type in a new module
xianxu has joined #ocaml
<companion_cube>
otoh ocaml has private aliases ;)
<jpdeplaix`>
companion_cube: no, it's not the same as the Haskell's (.)
<companion_cube>
sure, but reverse composition is nice too
<Drup>
companion_cube: sure, but the features are not exactly the same
<def-lkb>
(Custom operator precedence introduce a nasty dependency between scope resolution and parsing… With an ML-like module system, it turns into a really bad idea)
<Drup>
(I agree with def-lkb on this one)
<Drup>
(It's a good idea in haskell, it would be a bad one in ocaml)
<Drup>
(and even in haskell, in can turn into a nightmare quite quickly, especially since there is no local open)
<knz>
jpdeplaix`: do you know of other places that define (%) in the same way as batteries included?
<knz>
I never uses batteries before
<knz>
I did not know they were common
<Drup>
knz: oh, you didn't mention that haskell identifier were fully utf8 compliant !
<Drup>
it's quite important, compared to ocaml
avsm1 has joined #ocaml
<smondet>
Drup: utf8 identifiers are like type-classes, cool idea, but in practice, 95% of their use is for making code unreadable :)
<adrien_oww>
APL in Haskell \o/
xianxu has quit [Ping timeout: 265 seconds]
<Drup>
smondet: I agree, but don't tell that in front of an haskell developer
<Drup>
(typeclasses are more useful than uf8 identifier, though :D)
<companion_cube>
I think typeclasses are awesome
avsm has quit [Ping timeout: 240 seconds]
* adrien_oww
gags companion_cube
<Drup>
companion_cube: you never debuged some Haskell code with more than 5 typeclasses in the same expression.
<knz>
Drup: I would be seriously worried if an OCaml developer would choose to learn Haskell because of unicode identifiers...
* companion_cube
slaps adrien_oww with a giant trout
<Drup>
knz: I think you missed the point of why an Ocaml would read your blog post
<knz>
I will use my privilege as author to avoid promoting this :)
<Drup>
(still, I wouldn't talk about unsafePerformIO)
<knz>
hahaha
<knz>
Haskell people do not talk about unsafePerformIO, like OCaml people do not talk about Obj.magic.
<Drup>
exactly :D
<Drup>
(I was going to do the comparison :)
<knz>
:)
<Drup>
I don't recall my other issues when I started Haskell, I'll tell you if I remember one
<companion_cube>
monad transformers?
demonimin has quit [Ping timeout: 240 seconds]
<Drup>
that's not specific to Ocamlers
<Drup>
knz: oh, maybe give a little link to the documentation of the State monad, since you need it very fast when you come from the ocaml world
<Drup>
except the fact that I think it should be more neutral (it's very biased towards "haskell is fantastic" :p), It's a good initiative and it's useful. I lacked something like that when I started haskell
<Drup>
( companion_cube : but yes, monad transformers are a nightmare )
<Drup>
( lot's of haskelers like them x)
<jpdeplaix`>
« since you need it very fast when you come from the ocaml world » Really ? What is your use case ?
<Drup>
a unique name generator is the first thing I developed
<Drup>
in ocaml, it's just a ref and counting, with some impure stuff
<Drup>
basically, most time you use a reference in ocaml, you don't really want an IORef, you want a State
<Drup>
(and it's useful anyway)
demonimin has joined #ocaml
* companion_cube
likes the visitor pattern
avsm1 has quit [Quit: Leaving.]
avsm has joined #ocaml
csakatoku has joined #ocaml
<knz>
Drup: state is important, but I can't find a compelling use for it that I could explain without using the word "monad"
lostcuaz has joined #ocaml
lostcuaz_ has joined #ocaml
xianxu has joined #ocaml
<Drup>
^^
<Drup>
I think lot's of reasonably advance ocaml users know what a monad is
<rks`_>
naaah Drup
<rks`_>
they think they know, like rubyists think they know
<rks`_>
but caml users are basically reconverted java coders
<Drup>
and talking about haskell without using the M word is slightly misleading :3
<rks`_>
they cant possibly understand
<rks`_>
you should have read knz article, it's very interesting
<adrien_oww>
rks`_: I'm happy you've finally accepted what you really are
<companion_cube>
local modules are really nice
lostcuaz has quit [Ping timeout: 264 seconds]
<ggole>
It's true: OCaml is Java with variants
<Drup>
:D
<Drup>
Java even have lambdas know !
<companion_cube>
no yet
ulfdoz has joined #ocaml
<Drup>
now*
<companion_cube>
(unless java 8 was released?)
* companion_cube
starting to like more and more the error monad in OCaml
<rks`_>
adrien_oww: yes well, thank knz, he opened my eyes
<jpdeplaix`>
:D
xianxu has quit [Ping timeout: 252 seconds]
ollehar has quit [Ping timeout: 240 seconds]
ulfdoz has quit [Ping timeout: 244 seconds]
<gasche>
knz: unsafePerformIO is horrible and a disservice to beginners reading your document
avsm has quit [Quit: Leaving.]
<gasche>
use Debug.Trace
ygrek has joined #ocaml
<gasche>
knz: I second Drup's advice to use State rather than IOrefs to emulate OCaml references
<gasche>
the ST monad should also be mentioned for local use of state
<companion_cube>
o/ gasche
<gasche>
I'm also missing mentions of polymorphic variants (as something that Haskell lacks), lenses (to provide something better than records), and both the upsides (modularity + some nice design patterns such as memoized-through-an-array) and downsides (memory leaks) of lazyness
<gasche>
also a discussion of why you generally shouldn't care about tail recursion in Haskell
<gasche>
(OCaml programmers will try to use foldl instead of foldr)
<gasche>
re. leaks, the document should definitely mention the sheer difficulty of controlling performances of Haskell code
<gasche>
ah, and you don't give justice to type classes, I think
<gasche>
they're better than just "operator overloading"
<Drup>
I agree with that
<Drup>
the "encoding the Map functor with the Ord typeclass" example is the one that makes me "click"
<companion_cube>
or just for a correct treatment of equality
<ggole>
(Also objects: but you can probably just leave those out.)
<gasche>
I'd say objects are anecdotal but polymorphic variants are important
<knz>
wait wait
<knz>
what's the difference between ST and State?
<companion_cube>
the underlying implementation
<ggole>
Mmm, polymorphic variants do seem to be used considerably more
<knz>
ok thanks
<jpdeplaix`>
ggole: mmh I don't think so :D
<companion_cube>
objects are still a nice thing to have
Thooms has joined #ocaml
adrien_oww has quit [Read error: Operation timed out]
travisbrady has joined #ocaml
<smondet>
gasche: I would be curious to know why lenses would be better than records? There was a Lens tutorial/presentation at NYC-Haskell, it makes code uglier than perl
mort___ has joined #ocaml
<companion_cube>
I think it's because lens updates/accesses are composable
adrien_oww has joined #ocaml
<companion_cube>
if you have deeply nested records/lists you can modify one that is deep
divyanshu has joined #ocaml
<flux>
hmm, I haven't looked into lenses, but wouldn't you use them for updating such records, not replace them?
<gasche>
I think you want the language to have both lenses and records (just as you want both references and get/set pairs); but if you mention that Haskell doesn't have records, you should point out that Lenses do a good job in absentia, even surpassing them in many respects (as companion_cube says, you can abstract over deep accesses)
<flux>
maybe I need to look better :)
<gasche>
(I got the order wrong: record:lenses :: references:(get,set); higher-level, less syntactically convenient, potential performance issues, more flexible and composable)
arjunguha has joined #ocaml
adrien_oww has quit [Ping timeout: 240 seconds]
adrien_oww has joined #ocaml
<companion_cube>
I think you want both OCaml functors and haskell's typeclasses, also
<gasche>
knz: ST has both single references and arrays, and gracefully degrades into IO (so you can take an IO+IORef code and turn it into ST easily, and then improve locality of effects incrementally)
<gasche>
State doesn't do arrays very well, and you cannot convert back and forth from IO
<Drup>
companion_cube: I do not want to imagine the mess it would be to have both + first class modules and functors
<knz>
ok guys
<Drup>
you could potentially have typeclasses appearing in your code, that would be a total nightmare.
<ggole>
I sometimes wonder what OCaml would look like if array/string elements and mutable fields were integrated with references
<knz>
I have added a treatment of type classes and monads
claudiuc_ has quit [Remote host closed the connection]
<ggole>
eg, a.(i) += 2 would work
RMacy has joined #ocaml
<ggole>
(Noisier, probably, since you'd have to deref all the time.)
<knz>
ggole: that's what ArrayRef was intended to solve, iirc
<companion_cube>
Drup: I don't like much first-class modules...
<companion_cube>
I'd rather have typeclasses
<gasche>
the core of type classes is type-directed code inference
<Drup>
I'd rather have just implicit, and not full typeclasses
<gasche>
this is orthogonal to what we have in OCaml right now
<companion_cube>
Drup: that would remove big warts OCaml currently has
<companion_cube>
implicits are more dangerous imho, because you give more power to the user
<companion_cube>
power that can be used for implicit coercions, etc.
<Drup>
huh, no.
<jpdeplaix`>
wat ?
<Drup>
not more than typeclasses
Enjolras has joined #ocaml
<companion_cube>
Drup: scala has implicits, and they are sometimes used for terrible things
<companion_cube>
like, implicitely carrying a database connection in a bunch of code
<companion_cube>
maybe there are less powerful implicits, though
<knz>
Drup: is my treatment of typeclass sufficient do you think?