<Gertm>
but it's yet another little language nobody uses?
<Smerdyakov>
I'm using it, and I think many more will be soon. :)
<Smerdyakov>
And it probably passed the point of qualifying as "little."
<Gertm>
nevermind my comment, I don't want to say negative things of stuff I don't know anything about
<Smerdyakov>
Ur/Web is so far beyond any of the competition, any sentence with "yet another" is probably wrong. :)
<det>
DISCLAIMER: Smerdyakov is the author!
<Gertm>
ah, ocamlnet has the base64 functions I was looking for
<flux>
gertm, I have nntp module around if you have a need for it - I wrote the somewhat the reverse what you're doing, it converts nntp into rss
<Gertm>
thanks flux, I'll keep it in mind
<Gertm>
as I go I try to get my head around OCaml.. I fear it's going to end the same way for me as Haskell did... headaches and despair
<Gertm>
but atleast I have stuff working already! The future is bright.
<flux>
you'll do just fine ;). which languages are you familiar with?
<thelema>
Gertm: ocaml is much less headache inducing than Haskell
<Smerdyakov>
thelema, depends on your perspective. Bugs based on imperativity are some of the champion headache-inducers. :P
<thelema>
Smerdyakov: but bugs based on lazy evaluation are just trivial to find?
<Gertm>
for a living: C#, in my spare time (and some little stuff at work) I've tried: Common Lisp, Haskell, Erlang, and now OCaml.. (and some dabbling with python and those languages)
<Smerdyakov>
That's why I'm for pure & strict languages. :)
<thelema>
Smerdyakov: fair enough.
<Gertm>
I stumbled upon ocaml through F# (which I quickly abandonned for ocaml)
<Gertm>
I left CL because of the library hell, haskell because it's just too hard/impractical and Erlang because of lack of types.
bzzbzz has joined #ocaml
bzzbzz has quit [Client Quit]
bzzbzz has joined #ocaml
<Smerdyakov>
Gertm, Haskell isn't "impractical" in some absolute sense. Many people are using it for practical purposes.
<Gertm>
Smerdyakov: I meant to say, impractical for me.
<Smerdyakov>
Gertm, how did you decide that it wasn't worth learning more, so that you might get better at using Haskell?
<Smerdyakov>
Feel free to wave me away at any time. :P
<Gertm>
I got tired of it, wanted to try something else.. Tried Erlang and it was a breath of fresh air
<Gertm>
but then I started to miss the types
<Gertm>
are you using haskell? do you prefer it over ocaml? why (not) ?
<Smerdyakov>
I only mean to point out that most students of new ideas feel like they're "tired of them" early on, even if they end up later being glad that they persevered.
<Smerdyakov>
I've never done any non-trivial Haskell programming, but I do mostly program in pure languages.
<Smerdyakov>
(Coq and Ur)
<Gertm>
Yea, I should probably persevere.. so do you recommend doing that in haskell or in ocaml?
<Smerdyakov>
I do agree that OCaml is more practical, but I like purity and type classes, so it's a shame. Ur has all of the above. :)
<Gertm>
ocaml is better for me atm, because I can actually write stuff easily
<Smerdyakov>
You could say the same thing about physics problems that can be solved easily without calculus.
<Gertm>
maybe I shouldn't write in this type of language if I want to do it easily?
<Smerdyakov>
If you want it to be easy to write a program that is _almost_ right, then I agree.
<Smerdyakov>
If you want to get it right, there isn't much other choice. :P
<Gertm>
let me get my C++ programming colleagues in this discussion ;)
<Smerdyakov>
Also, experienced functional programmers find functional programming to make almost everything easier.
<Smerdyakov>
For simple programming problems, though, few such decisions matter.
<Gertm>
I believe that, and I want to become more fluent in functional programming
<Smerdyakov>
So I should revise my description to: "Mainstream languages make it easier for the average programmer to get simple programs mostly right." :)
<Gertm>
ok, going to step off the path to flaming now
rwmjones has joined #ocaml
<Gertm>
what book/tut/guide whatever would you recommend for an 'average' programmer to learn purity and type classes then?
<Smerdyakov>
I don't know. Try www.haskell.org for their advice.
<Gertm>
Yeah, I've done that.
<Gertm>
Tried to read the typeclassopedia but had to scrape my brain off the walls after 4 pages
<det>
Type classes are a really nice concept
<det>
The things I'd take from Haskell for Ocaml are type classes and existential types (I'd ditch purity and laziness)
<Smerdyakov>
You can encode existential types with first-class, higher-kind polymorphism.
<Smerdyakov>
Gertm, read "Types and Programming Languages," by Benjamin Pierce.
<Gertm>
oh, I have to buy that?
<det>
Smerdyakov, that solution is awkward in comparison
<Smerdyakov>
det, of course. :)
<Smerdyakov>
Gertm, or library it, or break the law. :)
<Gertm>
can't find it :|
<Smerdyakov>
I haven't yet wanted existential types in Ur, actually. What's your big use case, det?
<det>
Smerdyakov, mostly in combination with type classes
<Smerdyakov>
det, can you be more specific?
<det>
Smerdyakov, You need them in order for to have a list of some some instance of a class
<Smerdyakov>
det, oh, gotcha. Not necessary in Ur. :)
<Smerdyakov>
My online demos have a few such examples.
<Smerdyakov>
You just index the list by a type-level list of types.
<det>
You mean like ADTs ?
<Smerdyakov>
This only works for lists of statically-known shape, but I haven't wanted more yet.
<Smerdyakov>
And you can encode existential types nicely as a library in Ur if you really want, since Ur has first-class, higher-kind polymorphism.
<Smerdyakov>
det, I don't understand.
ulfdoz_ has joined #ocaml
Gooffy has joined #ocaml
<Gertm>
seems google books has it entirely
<det>
Smerdyakov, I'm not sure what your type indexing means, but it sounds like ADTs (type a = A of blah | B of foo | C of baz)
<det>
Smerdyakov, does Ur have type classes?
<Smerdyakov>
det, Ur has constructor classes, yes.
<Smerdyakov>
Here's an example of a list of 'show'able values.
<Smerdyakov>
con which_types :: {Type} = [A = int, B = float]
<Smerdyakov>
val which_values : $(map (fn t => show t * t) which_types) = {A = (_, 3), B = (_, 4.5)}
ulfdoz has quit [Ping timeout: 264 seconds]
<det>
what is con
<Smerdyakov>
"Constructor." Generalizes "type."
<Smerdyakov>
(higher kinds)
<Smerdyakov>
Also, in this example, you could replace 'which_types' with '_' in the second line, and it would be inferred.
<det>
so, after first colon is some type language
<Smerdyakov>
Or constructor language, depending on how you want to think about it.
<Smerdyakov>
It's a constructor of kind 'Type'.
<Smerdyakov>
With some intermediate constructors of other kinds
<det>
Do you often feel the need for such power?
<Smerdyakov>
Yeah. Look at my demos for examples like building a web site customized to a database schema.
<Smerdyakov>
(Implemented as a statically-typed functor)
<det>
What does "{A = (_, 3), B = (_, 4.5)}" mean ?
pimmhogeling has joined #ocaml
<Smerdyakov>
"This is a record. It has two fields, 'A' and 'B'. Each field is assigned a pair. The pairs' second components are '3' and '4.5'. Infer the first components for me."
<Smerdyakov>
(The first components are type class witnesses.)
<det>
And you can use this to build a list of ints or floats and show them ?
<Smerdyakov>
You can write a function to show any record (of statically-known type-shape) of values in any types belong to the 'show' class.
<det>
Ok, I get it now.
<det>
I think, usually you would have only 1 constructor in your record ?
<det>
I mean, field
<Smerdyakov>
Are you referring to the type-level or value-level record?
<det>
I think value level
<det>
Why did you have the rhs of the = have 2 fields ?
<Smerdyakov>
Because you need proof that this type belongs to the type class.
<Smerdyakov>
You could also do it as two separate value-level records.
<Smerdyakov>
Which would actually be prettier, now that I think of it. :)
<Smerdyakov>
Your example doesn't include the implementation of the 'show' instance for aggregate types.
<Smerdyakov>
Thus, you should only compare against the last line of my example.
<Smerdyakov>
No datatype definition needed beforehand
<det>
Can you translate that simple Haskell into the Ur equivalent ?
<Smerdyakov>
I think the examples I've already given show how I do similar things.
<det>
Well, they are all working with records and closed sums
<Smerdyakov>
I wouldn't say there are any sums involved.
<Smerdyakov>
Ur contains System Fomega as a sublanguage, so it's obvious how to encode existential types; thus, I won't go into it.
<Smerdyakov>
I only mean to suggest that you only turn to existential types, in many cases, because of the impoverished type system. My examples avoid existential types.
<det>
Is there any reason you use records instead of lists, in your examples?
quelqun_dautre has quit [Ping timeout: 245 seconds]
<Smerdyakov>
'showRecord' works on tuples, too, which are just records with numbers as field labels (like in SML).
<Smerdyakov>
If you're going to fix the shape statically, this is equivalent to lists.
<Smerdyakov>
Lists are homogeneous by construction, so you can't use it directly in this way.
<det>
Is a Ur record fixed at construction? can you add a field later? similar to prepending to a list ?
<Smerdyakov>
r ++ {Foo = 3}
<Smerdyakov>
I think we've reached the point where you should consult the Ur documentation if you want such details. :P
<det>
I think that your examples using records arent the same as what I was talking about.
<det>
But Ur definately looks interesting and I will look into .
<det>
<det> Smerdyakov, You need them in order for to have a list of some some instance of a class
<Smerdyakov>
There are no programs whose specifications say "must involve lists of class instances." It's an implementation technique, and I'm arguing that it's pretty unimportant.
<det>
The whole point of that the container is dynamic, of unknown length, so I would assume this implies homogeneous
<Smerdyakov>
It's a niche feature, and Ur supports it better than Haskell does. I was only telling you a better way of doing it when shape is known statically.
<det>
I guess I dont see why your way is any nicer than using an existential type
<Smerdyakov>
No run-time recursion is needed. Everything gets expanded by the compiler.
<det>
Ahh, good point.
<Smerdyakov>
And it's always nice to use types to make explicit which aspects of program behavior are fixed.
<Smerdyakov>
And you can express relationships between different "lists," where the relationships are nonsense unless you have names for the different "existential types."
yakischloba has joined #ocaml
dark has joined #ocaml
avsm has joined #ocaml
<bjorkintosh>
has anyone here attempted to read the definition of standard ml book?
<Smerdyakov>
See, that code strikes me as dramatically ugly, because it's treating URIs as arbitrary strings.
Yoric has joined #ocaml
<thelema>
Smerdyakov: I think that's the point - it's dirty, but *hella* quick.
<Smerdyakov>
Ur/Web is just as quick, without being dirty.
<dark>
aren't uris arbitrary strings anyway? (are you talking about that get '/hello/:name' do |n| ..?)
<Camarade_Tux>
no, not completely arbitrary
<Smerdyakov>
dark, I am.
<Smerdyakov>
dark, here's the example no one seems to be thinking of: composing a web site out of components. How do you coordinate the URL mapping across components?
<flux>
I really would like to compose websites out of components
<flux>
or, rather, would have liked a few years ago, the current system is difficult to retrofit :)
<flux>
it does indeed have the concept of components, but there is no automatic coordination involved.
<Smerdyakov>
This is very easy to do in Ur/Web.
<dark>
one could use a function to build the uri
<dark>
Smerdyakov, the problem is that uris aren't meant to change
<Smerdyakov>
Also consider this: a higher-order function that is parameterized over a page generator.
<dark>
once you have a url, you need to support it forever in most cases
<Smerdyakov>
How does the higher-order function know which URL to use?
<dark>
if you want to change, you need hooks for the old urls
<Smerdyakov>
Can you be sure you aren't making a mistake with whatever ad-hoc URL-scheme-passing scheme you concoct in a more traditional language?
<dark>
hm
<Smerdyakov>
dark, Ur/Web supports that very simply.
<Smerdyakov>
dark, your application is an ML-style module.
<flux>
smerdyakov, however, I would also like to know the urls, instead of relying on automatic generation. does Ur/Web support that as well?
<Smerdyakov>
dark, the URLs of the kind you mention correspond to the page generators exposed in the module's signature.
<Smerdyakov>
dark, the language spec gives you guarantees about how URLs will look, as a function over a module signature.
<Smerdyakov>
flux, yes. There is a standard lib. function from page generator functions to URLs.
<Smerdyakov>
flux, plus the fixed URL generation scheme I just mentioned.
lokydor has quit [Ping timeout: 245 seconds]
Yoric has quit [Quit: Yoric]
Drk-Sd has quit [Quit: {'EXIT', Drk-Sd, "bye"}]
avsm has quit [Quit: Leaving.]
vpalle has quit [Quit: Leaving]
_andre has quit [Quit: Lost terminal]
lokydor has joined #ocaml
pimmhogeling has joined #ocaml
<hcarty>
thelema: Do you know if the keys and values functions from the BatMap modules give their results in sorted order, like in the iter and other functions?
ulfdoz_ has quit [Quit: Reconnecting]
ulfdoz has joined #ocaml
<thelema>
yes, they do.
<thelema>
lowest to highest.
<hcarty>
Good, thank you
<thelema>
umm, by key.
<thelema>
iirc, they're just projections of the Map.enum function
<hcarty>
Right
<thelema>
let keys t = BatEnum.map fst (enum t)
<thelema>
let values t = BatEnum.map snd (enum t)
<thelema>
yup.
<hcarty>
Looks like it - I'm just not sure I was following the logic of the enum function correctly
<thelema>
a bit lazy, but definitely correct.
<hcarty>
Thanks for the clarification
Drk-Sd has joined #ocaml
<thelema>
ah, the .enum functions can get a bit scary.
<thelema>
umm, n/m... it's not in order...
<thelema>
at least according to my reading, it should return the root very first...
Drk-Sd has quit [Client Quit]
<thelema>
odd - batSet has a totally different .enum function
<hcarty>
Oh well - I'll have to grab the (key, value) enum and sort on that
<thelema>
BatPMap's enum is in order... I'm guessing this is an early implementation of [enum]
<hcarty>
Should I submit a bug report/feature request?
<thelema>
I think I've already fixed it... testing now.
<thelema>
fixed. pushing to git...
<thelema>
ok, pushed
<hcarty>
thelema: Cool, thank you
<mfp>
would benefit from the same impl as BatSet (IIRC it was 2-3X faster than the one with Enum.append/delay)
<thelema>
yes, it would. That goes on the todo, for someone wanting to contribute.
<mfp>
thelema: [bb7188094ae] do you need to go through BatList? BatSet's orig code was
<thelema>
if we're going to fix this implementation, we might as well fix PMap as well, which is where I cribbed the implementation from.
<mfp>
k
pad has joined #ocaml
quelqun_dautre has joined #ocaml
<thelema>
What should I call this: [let pipe x f = f x; x] - is "pipe" ok?
<thelema>
err, let pipe f x = f x; x
<mfp>
thelema: IIRC it's called "tap" in Ruby
sapsi has joined #ocaml
no_names_left has joined #ocaml
<thelema>
that's nice and short.
<flux>
why pipe/tap x f and not f x? (am I missing some obvious way to use it?)
<thelema>
flux: you're right - it's tap f x = f x; x
sapsi has quit [Quit: sapsi]
yanger has joined #ocaml
joewilliams_away is now known as joewilliams
yanger8 has joined #ocaml
yanger8 has quit [Client Quit]
yanger8 has joined #ocaml
* thelema
adds [tap] to Pervasives
<thelema>
The nect batteries will be 1.1
<thelema>
*next
yanger8 has quit [Quit: Java user signed off]
<hcarty>
thelema: PMap -> Map.PMap, bug fixes, tap - what else is new/planned for 1.1?
<thelema>
hcarty: umm, PMap -> Map
<thelema>
Need documentation fixes, build instructions
<hcarty>
Oh - what happens to Map?
yanger has quit [Quit: yanger]
<thelema>
map stays - everything in map is a submodule.
<thelema>
it'll become like hashtbl - you can use it directly for polymorphism or with a functor for extra safety
<hcarty>
Very nice
<thelema>
thank jharrop - he contributed that gem.
<thelema>
upon reflection, it seems obvious, but I definitely didn't come up with it.
<thelema>
ick, had to include all of batPSet.mli into batSet.mli -- modules should define a module type too.
no_names_left has left #ocaml []
<infoe>
harrop <3
<hcarty>
An "include" in the .mli, dragging in ocamldoc comments with it, would be a nice thing to have.
Narrenschiff has joined #ocaml
<thelema>
TODO: get rid of batStd/BatPervasives duplication
<thelema>
hcarty: exactly
<thelema>
changes pushed. We'll probably have batteries 1.1 by the weekend.
<hcarty>
thelema: Will PMap be kept around for 1.0.x compatibility?
<thelema>
yes, sadly.
<hcarty>
One day, Batteries 2.0 will come along and save us all :-)
<thelema>
It'll be deprecated as soon as I can note this in the docs, and will be dropped around 2.0 (except for possibly keeping ExtLib compatibility)
<thelema>
back later tonight.
<hcarty>
thelema: I need to leave as well, but I like the idea of a Batteries.Labels (or similar) option, as well as a Batteries.Exceptionless option.
_zack has quit [Ping timeout: 260 seconds]
mutew has joined #ocaml
jcaose has quit [Ping timeout: 256 seconds]
mutew has quit [Quit: leaving]
Submarine has quit [Ping timeout: 260 seconds]
pad has quit [Remote host closed the connection]
seafood has joined #ocaml
seafood has quit [Client Quit]
lokydor has quit [Ping timeout: 240 seconds]
bitbckt has quit [Remote host closed the connection]
Drk-Sd has joined #ocaml
bitbckt has joined #ocaml
Narrenschiff has quit [Quit: Narrenschiff]
ikaros has quit [Ping timeout: 265 seconds]
ikaros has joined #ocaml
ulfdoz has quit [Read error: Operation timed out]
Yoric has joined #ocaml
Drk-Sd has quit [Ping timeout: 248 seconds]
pimmhogeling has quit [Ping timeout: 256 seconds]
Drk-Sd has joined #ocaml
ikaros has quit [Quit: Leave the magic to Houdini]