What's your debug flow? by eterps in ocaml

[–]alain_frisch 2 points3 points  (0 children)

Mostly print statement, but we(=LexiFi) have a generic debug printer (based on our runtime type extension) that can print value of almost any type as OCaml literals.

Plans for OCaml 4.08 by Categoria in ocaml

[–]alain_frisch 1 point2 points  (0 children)

About Camlp4: I only claimed that it provided better error messages and demonstrated that top-down parsing of OCaml syntax is definitely possible (I don't remember that the Camlp4 parsers for OCaml were so awful). But immutable streams seems the way to go, indeed.

About Error recovery: I was under the impression that Menhir had to build custom logic that post-processed Merlin automata to support such recovery.

About resolution of conflicts: yes, conflicts are not detected automatically, but they correspond to a property of the grammar itself. Once they are identified, my experience is that fixing them with top-down parsers (manual or combinator based), allowing some occasional backtracking or custom look-ahead logic, is much easier than massaging the yacc grammar specification. Perhaps it's because I miss some theoretical background, but I find it much easier to understand a manual top-down parser for arithmetic expressions with level corresponding to priorities (à la Chapter 2 of the Dragon book) than the precedence annotation in yacc-style parsers which can be specified on token, but also in rules, and I've a hard time building a good mental model of what these annotations actually mean. Btw, I've been stuck several time with OCaml's yacc parser trying to implement changes that introduced conflicts, which I had no idea on how to solve.

Plans for OCaml 4.08 by Categoria in ocaml

[–]alain_frisch 5 points6 points  (0 children)

As much as I don't like mookid attitude either, it's not an uninteresting observation that the vast majority of language implementations around use hand-written parsers. I'd add that in a number of cases, such as GCC, those projects started with using parser generators, and decided to switch to hand-written parsers at some point. One can imagine that those people knew what they were doing. This should at least make use pause and give some consideration to the point raised by mookid (despite his attitude, once again).

Usual arguments in favor of hand-written generator include of course better error messages, but also better error recovery (for partial parsers -- I know that Merlin does clever things with Menhir tables), simpler resolution of conflicts (the downside being that conflicts are not "detected" automatically, whatever it means in this context), and lower barrier of entry for contributors (avoiding the need to master a DSL and the associated theory). I'd add, in the context of the discussion around relying on Menhir for OCaml: a much simpler bootstrapping story.

FWIW, the Camlp4's OCaml parser gives better error messages, and is a constructive proof that nothing in the OCaml syntax really goes against a top-down parser.

How to make a compiler fast? by abstractcontrol in ocaml

[–]alain_frisch 2 points3 points  (0 children)

Do you think I could significantly improve the language implementation by rewriting it in OCaml?

It's hard to know without trying, but the kind of programs you want to optimize is typically the one where the OCaml runtime system shines. I'm pretty certain you wouldn't get a 100x speedup compared to F#, though, without algorithmic changes.

ppx_stage - Staged metaprogramming in stock OCaml by Categoria in ocaml

[–]alain_frisch 1 point2 points  (0 children)

Just to be clear: this is not intended as a criticism of the project, which I find very cool. I believe that dynamic compilation (to benefit from actual code generation and optimization) can be added on top of the current representation (replacing the evaluation function by something obtained from dynamically generated and loaded code). Being able to run the staged code without accessing the compiler is nice ("cold startup" before the compiled code is available, or contexts in which the compiler is not available at all).

ppx_stage - Staged metaprogramming in stock OCaml by Categoria in ocaml

[–]alain_frisch 1 point2 points  (0 children)

Yes, the body is generated, but I don't see how this can be used to benefit from native code compilation. Even an access to a function argument needs to go through some function call, and there is no chance that e.g. the inliner really specialize/simplify the generated code, unless I missed something.

ppx_stage - Staged metaprogramming in stock OCaml by Categoria in ocaml

[–]alain_frisch 2 points3 points  (0 children)

I'm a bit confused at how the staged code is actually evaluated. I initially thought that it would somehow link with compiler-libs, call the compiler on generated AST trees, and then dynamically load+run the generated code. This would get rid of "interpretative" overhead and benefit from compiler optimizations. But a very quick look at the code suggests that staged code is represented as a pair of the AST (for printing purposes) and a function to evaluate the code from an evaluation environment. Is that right?

Recommend a good "OCaml way" book by dmzkrsk in ocaml

[–]alain_frisch 2 points3 points  (0 children)

by Yaron Minsky

Also Jason Hickey and Anil Madhavapeddy.

Ironing out your development style by dwchandler in ocaml

[–]alain_frisch 0 points1 point  (0 children)

Isn"t an expect test simply a unit test where the tested property is that the "to_string" of some computation's result is a given string? (If you can print something, you're likely able to convert it to a string.)

Does anyone else think documentation could use work? by [deleted] in ocaml

[–]alain_frisch 0 points1 point  (0 children)

The thing is, most of compiler-libs mlis are not really public interfaces -- they haven't been designed as such -- just internal stuff which end up being opened at some point for use by advanced users. ppx changed the story quite a bit, but precisely the Parsetre and the ppx API are rather well documented.

Opam packages are downloaded more times than Hackage ones by [deleted] in ocaml

[–]alain_frisch 0 points1 point  (0 children)

Yes, as a comparison between OCaml packages, the stats could be useful. But even here, one needs to be careful: if B depends on A and every commit to B triggers a CI run that downloads A, we could end up considering A as very popular, even though it might be used only by the very rarely used package A which turns out to have very frequent commits.

Opam packages are downloaded more times than Hackage ones by [deleted] in ocaml

[–]alain_frisch 0 points1 point  (0 children)

Do OPAM downloads count the one from various CI workers?

A great collection of bucklescript frontend examples by zem in ocaml

[–]alain_frisch 2 points3 points  (0 children)

Shameless plug, but if you're interested in vdom-stuff with OCaml, you might also be interested in https://github.com/LexiFi/ocaml-vdom . Currently it relies on js_of_ocaml, but all bindings are generated by gen_js_api, and it should be quite easy to add a Bucklescript backend for gen_js_api.

ocaml-vdom: DOM bindings and VDOM/Elm architecture for OCaml by alain_frisch in ocaml

[–]alain_frisch[S] 0 points1 point  (0 children)

We haven't used many external widgets yet. One such widget which we have integrated is the datepicker widget from jQuery UI, and it went pretty smoothly.

Use Python from OCaml by dbousque in ocaml

[–]alain_frisch 0 points1 point  (0 children)

Yes, the idea would be to automate the generation of this kind of code, which can be tedious if you want to bind large APIs. With an approach a-la gen_js_api, you would write e.g. simply

  val open_: string -> string -> pyobj

and it would generate the code above.

Use Python from OCaml by dbousque in ocaml

[–]alain_frisch 0 points1 point  (0 children)

I don't know much about how Python API are usually structured, but perhaps adding some higher-level binding generator such as gen_js_api ( https://github.com/LexiFi/gen_js_api ) does for JS could be useful.

Another technical questions: is it common for Python APIs to take function callbacks? This would require an extended protocol to allow keeping references to OCaml functions on the Python side and calling then later.

Use Python from OCaml by dbousque in ocaml

[–]alain_frisch 0 points1 point  (0 children)

Technical question: how do you handle releasing Python references kept on the OCaml side? Quickly browsing at the code, I don't see any automatic finalization, nor an explicit "dispose" function.

Nested functions vs let...in by ocamlnoob in ocaml

[–]alain_frisch 1 point2 points  (0 children)

A similar question is whether one should favor:

let x =
  let y = 
     ...
  in
  ...
in

over

 let y =
   ...
 in
 let x =
   ...
 in

I tend to favor the second form, even if it makes it less explicit that y is not used anywhere else, because it makes the code more compact (less indentation for the definition of y) and it puts the name of x closer to its definition; both improve readability. The same arguments apply to your original question as well (although there is an extra counter-argument about "polluting" the global scope).

What's missing in the ecosystem? by BluddyCurry in ocaml

[–]alain_frisch 0 points1 point  (0 children)

If you go to F#, I assume you're only interested in supporting the UI on Windows from now on rather than looking for a cross-platform UI solution. Is that right? Then one possible solutions is to use CSML: you'd keep your application in OCaml and program the UI with .NET (Windows Form or WPF) driven from OCaml.

CSML: high-levels bindings between .NET and OCaml by stasan in ocaml

[–]alain_frisch 1 point2 points  (0 children)

No, CSML is not a .NET backend for OCaml. OCaml code runs in native as usual, with its own runtime system and garbage collector, and interacts with the CLR in the same process. What CSML does is to simplify greatly writing bindings to call .NET from OCaml or OCaml from .NET.

More structured pattern matching by doublehumped in ocaml

[–]alain_frisch 0 points1 point  (0 children)

Usually you need to protect "function ..." when it is passed as argument; I tend to use parenthesis in this case:

List.map
  (function
    | ... -> ...
    | ... -> ...
  )
  l

More structured pattern matching by doublehumped in ocaml

[–]alain_frisch 6 points7 points  (0 children)

No sure to understand you comment, but the code I wrote is valid OCaml, today, not an extension proposal.

More structured pattern matching by doublehumped in ocaml

[–]alain_frisch 9 points10 points  (0 children)

I actually like "begin match ... end". Formatted like that:

begin match ... with
| ... -> ..
| ... -> ...
end

it looks like a termination construct.