Live data from Hacker News

OCaml Programming: Correct and Efficient and Beautiful

cs3110.github.io

151–160 of 251 posts

Re: OCaml Programming: Correct and Efficient and Beautiful

#151
post #21

Earlier quoted context omitted.

OCaml vs All: Good luck finding developers that will write quality code and not cost a fortune each.

If Jane Street can teach OCaml to traders, I can teach it to developers. That's not a concern for anyone other than a sweatshop.

Actually, what I found more impressive is that they also got them to use emacs.

Re: OCaml Programming: Correct and Efficient and Beautiful

#152
post #112

Earlier quoted context omitted.

The ML languages started appearing in the 70s. Rust is a very modern language. Where do you think rust got (more than) half of its type inspiration from? Either way no one has to use any language. Personally OCaml is not my cup of tea--Haskell is. But it is a great tool and it's solving hard problems.

I used StandardML at university in the early 2000s, and I appreciate that OCaml is an older language that heavily influenced the design of Rust. Given that history, it’s instructive to note the sorts of things (like auto-currying) that Rust did not inherit.

Rust is a different language with a different audience.

If a functional language is presented today that does not automatically curry calls, I have no interest.

Just because the tool does not work for you does not mean there's a defect in the design.

Re: OCaml Programming: Correct and Efficient and Beautiful

#153
post #146

Earlier quoted context omitted.

Do you have any examples? Unfortunately from my perspective, I cannot make sense of your statements. OCaml typing is principal in all situation where type inference is decidable. The syntax for annotation for polymorphic functions is isomorphic between OCaml and Haskell. If I take a random module in the standard library, let's say Array, 95% of the functions in this module are parametric polymorphic. I am thus genuin…

I wrote up a bunch of grievance examples for a blog post I never got around to publishing, but I'm traveling at the moment so can't pull up my laptop. I'll see if I can find them later. > The syntax for annotation for polymorphic functions is isomorphic between OCaml and Haskell. Sorry, but total bullshit. I had to use these pieces of shit all the time. https://v2.ocaml.org/manual/locallyabstract.html > If I take a r…

> Sorry, but total bullshit.

Ok, locally abstract types are bit weird and historical quirk due to the pre-existing use of type variables as unification type variables. But first, they only matter with GADTs and local modules (a notion that doesn't exist in Haskell). And the good syntax for polymorphic function with GADTs is `type a. a monoid -> a` which requires just one explicit quantification compared to the Haskell variant. So no, Haskell and OCaml type annotations are isomorphic.

> As I specifically called out, all the core data structures are polymorphic.

I took a totally random module from the standard library! Let me another random module after rolling a dice, Atomic. Here only 66% of the functions are polymorphics. Or do you want me to go to another library? Ok, let's go for container, and let's select another random module CCPair: 100% of the functions are polymorphic. Honestly, I struggle to understand how it is possible to conclude that every OCaml library is monomorphic.

What do you mean by LATs? The Haskell wiki doesn't seem to know that term.

> The only polymorphic code that you can write in ocaml without such things are functorial

I am sorry to ask but are you confusing bounded polymorphism with parametric polymorphism?

Re: OCaml Programming: Correct and Efficient and Beautiful

#155
post #45

Earlier quoted context omitted.

yes, that would be a straightforward error message! But I got the error message Error: This expression has type ((locl_ty * Tast.pos * ('ex, 'fb, 'en) Aast.expr_) list -> Result_set.t) list but an expression was expected of type Result_set.t list Type (locl_ty * Tast.pos * ('ex, 'fb, 'en) Aast.expr_) list -> Result_set.t is not compatible with type Result_set.t Which is not half as readable.

With OCaml type system permanently burned in my mind, I parse that error message as "there is an ` _ -> Result_set.t ` arrow type which is not compatible with type `Result_set.t`". Do you think that the issue is that the arrow `->` is too hard to spot?

I have no insight into what is hard and what is easy to implement here, but might it be feasible to break up the error into parts, the first just as you wrote? Along the lines of:

1. Error: This expression has type ('x -> Result_set.t) list but an expression was expected of type Result_set.t list

2. where 'x = (locl_ty * Tast.pos * ('ex, 'fb, 'en) Aast.expr_) list

The solution suggested by the parent of your post sounds desirable also, but perhaps the currying semantics of Ocaml makes that difficult or poorly-defined?

Re: OCaml Programming: Correct and Efficient and Beautiful

#156
post #67

Earlier quoted context omitted.

With OCaml type system permanently burned in my mind, I parse that error message as "there is an ` _ -> Result_set.t ` arrow type which is not compatible with type `Result_set.t`". Do you think that the issue is that the arrow `->` is too hard to spot?

Yes, I think that's the issue. I built a reasonably popular typechecker for PHP, so I have some experience with the DX for these sorts of programs. I don't think it's good for a couple of ASCII characters and line breaks to be the difference between an acceptable and an unacceptable type annotation. It requires, as you say, for the OCaml type system to be burned into people's minds for them to immediately spot the is…

I think it would be great to address this as you describe, but at the same time as somebody who has dabbled in OCaml but is still very wet behind the ears, I don't understand how this error format requires the type system to be "burned into your mind".

Re: OCaml Programming: Correct and Efficient and Beautiful

#157
post #82
post #53

Earlier quoted context omitted.

Pattern matching without ADTs though loses a lot of the power. The fact that you'd still have to handle null/undefined cases means it's still annoying to use and hardly exhaustive.

erlang/elixir programmers would disagree -- we match on ad-hoc dynamically typed tuples that serve broadly the same purpose as ADTs all the time, where the only exhaustiveness you get is the degenerate case ie `_ -> shit_the_bed()` especially common are pattern-matching assignments (technically `=` is the “match operator”) that idiomatically behave much like matches on the left hand side of ` these communicate progra…

I write Elixir for work and I love most things about the language.

The pattern-matching would still be made better with static checks. It sucks to have a function blow up at runtime because of something as trivial as args being swapped or some code somewhere changing its return types. Someone brought up Gleam earlier, but god why with that syntax?

I'd still rather have dynamic checked pattern matching over the alternative.

Re: OCaml Programming: Correct and Efficient and Beautiful

#158
post #114
post #45

Earlier quoted context omitted.

yes, that would be a straightforward error message! But I got the error message Error: This expression has type ((locl_ty * Tast.pos * ('ex, 'fb, 'en) Aast.expr_) list -> Result_set.t) list but an expression was expected of type Result_set.t list Type (locl_ty * Tast.pos * ('ex, 'fb, 'en) Aast.expr_) list -> Result_set.t is not compatible with type Result_set.t Which is not half as readable.

For comparison, in Haskell you would get for this definition: myfun :: Int -> Char -> Bool myfun a b = undefined if you give too many arguments: myfun 1 'c' 3 • Couldn't match expected type ‘t0 -> t’ with actual type ‘Bool’ • The function ‘myfun’ is applied to three value arguments, but its type ‘p10 -> Char -> Bool’ has only two if you give too few arguments: putStrLn (myfun 1) • No instance for (Show (p20 -> Bool))…

Elm's developers have been working hard to make better error messages for these cases, and it really pays off even when experienced. Here are Elm's versions for comparison:

  > myfun 1 'c' 3

  -- TOO MANY ARGS ---------------------------------------------------------- REPL

  The `myfun` function expects 2 arguments, but it got 3 instead.

  5|   myfun 1 'c' 3
       ^^^^^

  Are there any missing commas? Or missing parentheses?

  > not (myfun 1)

  -- TYPE MISMATCH ---------------------------------------------------------- REPL

  The 1st argument to `not` is not what I expect:

  5|    not (myfun 1)
             ^^^^^^^

  This `myfun` call produces:

      a -> Bool

  But `not` needs the 1st argument to be:

      Bool

Besides being 'beginner friendly', this just takes away cognitive overhead when you can glance at an error message and immediately know what happened.

(Edit: Formatting. Note that in the console output the arrows actually line up with the source of the errors)

Re: OCaml Programming: Correct and Efficient and Beautiful

#159
post #27

I found my experience trying to work with a large OCaml base a nightmare — when signatures changed in an unstable dependency (e.g. function argument removed and nested inside another), the errors spat out by the typechecker were utterly incomphrehensible. This was largely due to automatic currying in OCaml — if I have a function call "some_function arg1 arg2" and "some_function" adds a third argument, that call becom…

Forgive my ignorance, I'd would like an example of the "functional" (hehe) benefits of automatic currying

Re: OCaml Programming: Correct and Efficient and Beautiful

#160

Earlier quoted context omitted.

let's see: - OCaml vs Haskell: eager vs lazy (=> memory consumption is more predictable) - OCaml vs Rust: OCaml has a GC (=> comfort) OCaml has tco (could not resist this ;) ) - OCaml vs Clojure: vastly superior typing system. (=> less bugs) - OCaml vs Kotlin: no JVM needed. - OCaml vs C++: more safety. once it compiles it will not segv. - OCaml vs Go: vastly superior typing system. (=> less bugs) - OCaml vs Python:…

I think the languages you selected in your final remark sum it up for me. If one is truly taken by functional programming, much of their mental model starts to revolve around algebraic (inductively defined) data types and structural recursion (aided by pattern matching) over them - such that mentally reducing the set of candidate languages really does become an implicit process of questioning: "does X have ergonomic,…

[deleted]
Post reply on HN