Earlier quoted context omitted.
The definition of list is: type 'a list = [] | (::) of 'a * 'a list When you write a list like: [x; y; z] This is syntactic sugar for: x::y::z::[] Which is syntactic sugar for: (::) (x, (::) (y, (::) (z, []))) One can imagine using more ordinary constructor names instead: type 'a list = Nil | Cons of 'a * 'a list And then the above would be: Cons (x, Cons (y, Cons (z, Nil))) In OCaml, data constructor names mar be ei…
Thanks for the detailed explanation. One more question though, when I write type 'a = 'a :: list 'a It is syntactic sugar that allows me to get the * product type for free, right ?
What I wish I knew when learning OCaml (2018)
81–88 of 88 posts
Re: What I wish I knew when learning OCaml (2018)
#82Re: What I wish I knew when learning OCaml (2018)
#83Earlier quoted context omitted.
I wonder why this is the case. Ocaml syntax doesn't seem very arcane, it is not hell-bent on functional purism and pragmatically allows for imperative code. Performance seems quite reasonable. What does it lack that prevented it from gaining wider acceptance? Surely buy-in from a large company was an issue, but even F# hasn't seen any significant uptake. Is it really the lack of curly brackets? That didn't stop Pytho…
The syntax is not great, the standard library is very sparse, and the error messages from the compiler and interpreter are terrible (and used to be worse). The OCaml team used to treat the native code compiler (ocamlopt) as a second-class citizen, but it's the implementation that matters for performance. Since the end of Dennard scaling about 15 years ago, OCaml's lack of multithreading has also been a pain point, on…
Re: What I wish I knew when learning OCaml (2018)
#84Earlier quoted context omitted.
I am not further enough in my F# journey to have tried this, but you could technically pair it with orleans for actor oriented systems ? Love the language though I have spent only a week working with it. It seems to have a lot of things I liked in Kotlin.
F# does have the `MailboxProcessor`. It is quite simple and capable. https://fsharp.github.io/fsharp-core-docs/reference/fsharp-c... https://fsharpforfunandprofit.com/posts/concurrency-actor-mo... I haven't looked at Orleans in a while. Last time I did, I came away with the viewpoint that it was very much designed to have a C# interface, which while manageable in F#, doesn't really provide for an idiomatic F# experie…
Re: What I wish I knew when learning OCaml (2018)
#85Earlier quoted context omitted.
The syntax is not great, the standard library is very sparse, and the error messages from the compiler and interpreter are terrible (and used to be worse). The OCaml team used to treat the native code compiler (ocamlopt) as a second-class citizen, but it's the implementation that matters for performance. Since the end of Dennard scaling about 15 years ago, OCaml's lack of multithreading has also been a pain point, on…
Then COBOL would be the scripting language for the mainframe, and C# would be the scripting language for Windows
Re: What I wish I knew when learning OCaml (2018)
#86Earlier quoted context omitted.
I'm not talking about Caml Light or even Caml Special Light, which is when the native-code compiler was initially added. 25 years ago was 01997. Objective Caml was released in 01996 (and renamed OCaml in 02011). Projects like KDE, the GIMP, GNOME, Lucene, Jython, LLVM, Asterisk, Audacity, CMake, and Danger that got started in C, C++, or Java in the 01997–02002 period are still based on those languages today. OCaml wo…
I have to ask: you're concerned about the year 9999 problem?
Re: What I wish I knew when learning OCaml (2018)
#87Earlier quoted context omitted.
I think both of these points can be alleviated with certain coding habits that come with practice. For instance, adding type annotations in some places will help with error messages. And using "assert false" (which has type 'a) will let you run an incomplete/broken program. As for the error messages requiring expertise in type theory, it sounds as an exaggeration, esp. when not using advanced features.
"adding type annotations in some places will help with error messages." I annotated the hell out of my programs, and completely avoided OCaml's type inference as much as I could because I saw that it could not guess what I meant. I still had tons of problems understanding the error messages. Error messages like "This expression is of type X but an expression was expected of type X" were not uncommon, and super frustr…
With experience, I am more or less able to preemptively add the annotations that will probably help (e.g. aiming avoid accidentally polymorphic functions, the return type of mutually recursive functions, etc.).
I don't think I have ever gotten "This expression is of type X but an expression was expected of type X" outside of the toplevel with type re-definitions, and recent OCaml versions have a nice error message for this now:
Error: This expression has type t/1 but an expression was expected of type
t/2
Hint: The type t has been defined multiple times in this toplevel
session. Some toplevel values still refer to old versions of this
type. Did you try to redefine them?
In general the error messages have been continuously improving in recent years.Re: What I wish I knew when learning OCaml (2018)
#88Earlier quoted context omitted.
It is equivalent to the following: type 'a list = Cons of 'a * 'a list | Tail ...but with a fancy syntax for Cons and Tail.
Ok. So in your example the construction action (placing two things next to each other IIUC) is done by the * product type Operator and Cons has no special meaning whereas if I had used ::, I actually get an the (::) name to refer to the left hand of the union and the construction action. Did I get that right ?
`type 'a t = Cons of 'a * 'a t | Tail` is defining a type with a constructor `Cons` with two arguments and a constructor `Tail` with zero argument. You write values of type `'a t` as `Cons (a, b)` and `Tail`.
`type 'a u = (::) of 'a * 'a u | []` is defining a type with a constructor `(::)` with two arguments and a constructor `[]` with zero argument. You build values of type `'a u` as `(::) (a, b)` and `[]`.
The rest comes from the special syntax support in OCaml for the `(::)` and `[]` names. Namely, `a :: b` is parsed as `(::) (a, b)`, and `[a; b; ...; z]` is parsed as `a :: b :: ... :: z :: []`, and hence as `(::) (a, (::) (b, (::) (..., (::) (z, []))))`.