Open source editor for iOS, iPadOS and macOS

Hello everyone,
I’m proud to share with you the editor I’ve been working on theses last weeks, which is also open source!

The editor is available here: App Store link
And the source code here: GitHub repository

A Pull Request just got merged, it is now part of the “Mobile” section on the Install page on the OCaml website.

Feel free to give your feedback, and/or contribute to the project on GitHub to help us to make a better tool!

10 Likes

I have dream, a day where this kind of app will be written in OCaml

3 Likes

It might me funny to do it, and the compiler would be totally native (no need to use js_of_ocaml), but that would need a lot of work for ui components etc to be done in ocaml (currently I have much more experience writing ios apps with swift)

I’ve done some experimental Cocoa bindings, and the basics are working, but the scope of the project is too large for a single person effort. Here’s an example basic app: ocaml-cocoa/count_clicks.ml at master · dboris/ocaml-cocoa · GitHub

Would be interested to contribute to a project with a similar goal, if someone has a better idea how to approach this.

Hi Nathan!
Well done :clap::clap::clap:!

I don’t have an iPhone, so I can’t test it out, but could you please detail (here and on the README on GitHub and maybe the page on the Apple store) if the app can be used offline or not?!
Calling it an “editor” without giving precise details about this key point could be misleading: for instance, a front-end to the https://REPL.it/ website could be called an editor, but it needs constant Internet access to run the code, and thus it does not allow to work and code offline and independently of a remote server.

Could you please detail this aspect? Thanks in advance!

  • For instance for Android, the only available app which works offline is 10-year-old, but still works fine as the OCaml code is interpreted locally: https://play.google.com/store/apps/details?id=fr.vernoux.ocaml
  • Similarly, I worked last month on the https://BetterOCaml.ml/ web app, now it can be installed as a “progressive web app”, on desktop with Chrome, or mobile with Firefox or Chrome. Thus it can then be used offline from the cache! As the OCaml code is interpreted in javascript in the browser, client-side.

If your app is usable offline, it’s great news for all the Apple exploited users, students and people who want to learn and use OCaml, without needing an active Internet connection and a trusted and online remote server.
I will add it to my list of apps for CPGE students in France: https://besson.link/apk.en.html#to-make-people-believe-that-we-are-still-in-prepa

Thanks in advance! – @Naereen

3 Likes

Jeffrey Scofield has built some iOS apps with OCaml, so it’s certainly possible: https://psellos.com/ocaml/compile-to-iphone.html

1 Like

Yes, this app can be used offline!

It works with a toplevel built with js_of_ocaml, stored in the app, and everything runs on the device (You can browse on GitHub the OCaml/JavaScript/ folder which contains the toplevel itself). So as everything is already built-in, no internet connection is required.

I will clarify it on the App Store page, because even if it was evident for me, I notice it is not for everyone.

Last thing, I’m myself in CPGE (MPSI to be exact), and that’s the reason why I started working on this app on my free time.

2 Likes

Thanks @NathanFallet for your quick and precise reply. I was almost certain that you would reply that, but indeed as you said “because even if it was evident for me, I notice it is not for everyone”! It’s a great habit to take to write longer documentation, especially when it’s for advertising about nice features!
You can read the documentation I improved for https://BetterOCaml.ml/, here: https://github.com/jbdo99/BetterOCaml/#sparkles-use-offline about its feature of being usable offline, and take inspiration to write some details about that.

It’s amazing to see these projects being produced by young students, working alone, at bac+1! Congratulations @NathanFallet !

I have a few other questions:

  • how is automated the build and the upload of the app on the App Store? If a new OCaml version comes every couple of months, how much time would it require to rebuild and upgrade the app and publish/update it on the App Store?
  • Can users save (export) and import .ml files? If so, advertise this feature too! Can users write in more than one file at a time (like it’s possible for BetterOCaml.ml in a single browser tab!)
  • I guess I know the answer but… the technology you chose to build the app is limited to Apple-products only, and it’s not a cross-platform technology like Flutter.dev or others recent technologies based on HTML/CSS/Javascript? If it is, how hard do you think it would be for you to also publish your app on Google Play store, and F-Droid.org ? The only app on Google Play is 10 year-old, for OCaml 3.12! https://play.google.com/store/apps/details?id=fr.vernoux.ocaml, it would be so great to publish a more recent and modern alternative!

Regards, and congratulations again! – @Naereen

1 Like

@jfrolich has done some bindings to UIKit too

To answer to your other questions:

  • I build the app manually, and upload the file to the App Store. So if a new version of OCaml is released, I need to rebuild the top level with Js_of_ocaml, and build a new version of the app that I upload.
  • Users can open and save their .ml files, and even open them from the file explorer (double click on a .ml file will open it in the app), it’s like a real code editor. For now only one file can be opened at time, but I plan to make a way to open multiple files (still thinking about it…)
  • Of course I wrote the app with pure Swift (except the top level which is built with JS), but an Android version of the app can be written without problem (it’s just about the user interface), and then published to the Google Play Store and whatever other store for Android phones.

As holidays are starting now in France, I will consider improving the app with feedbacks I got those last days, publish an update to the App Store, and start working on an Android version.

2 Likes

Amazing reply.

  • Okay for the manual rebuild. If it can be developed quickly enough, adding an automated build could be helpful (look into GitHub actions!). But beware of automation trap

Considering your studies, you should probably wait for the summer to work on the Android version.
If you do start working on the Android version, don’t hesitate to reach me I can test and help a little bit, and talk with the guy behind https://BetterOCaml.ml @jbdo99 on GitHub.
It should be smart to split the UI and the back-end as much as possible, to minimize the amount of duplicate work needed for the Android and iOS versions.

Even if you can’t update them in the future, a one-time published version of this app, on both Apple Store and Android Google Play is really a great thing to have for all students in France and CPGE (and elsewhere too!).
Pro FOSS tip: if you use only open-source software for your Android version (which most certainly will be the case), try to also upload it to F-Droid, as for now there are no FOSS version of OCaml toplevel on it (https://search.f-droid.org/?q=ocaml&lang=fr).

@nathanfallet, you could look for https://BetterOCaml.ml/ for ideas for features to add on your project, and you can also try the baby-version of a “native” Android/iOS app I made for this web-app, it’s still available to try from https://gonative.io/manage/hcf426x57rj9pktvuh1yqbn18w (using GoNative.io I had nothing to do but click and click).

1 Like

Nice work! I did something similar, but nice work in your repo! I optimized the Objective-C runtime bindings a little more by handwriting them and was pretty far along to make most things expressable in OCaml including blocks. I also managed to get it working in combination with brisk-reconciler a native “react” renderer for OCaml/Reason. I was able to write a simple app that talks to a graphql endpoint with graphql-ppx 1.0. I have limited time though, and the project is still in a very early stage so I didn’t share it on github yet, if you are interested I can add you as a private collaborator to consolidate our efforts.

I am currently looking into being able to compile both to iOS and the web with Melange. So my efforts have recently gone in that direction. Because I think this cross-platform nature will make it super compelling (just writing an app in OCaml alone will probably not make it that much better than writing a stand-alone app in swift).

3 Likes

@jfrolich Interesting. Yes, please add me as a collaborator to your project. Cross-platform iOS and Web development would be very compelling indeed.

Just updated the editor, I redesigned the macOS version, and it just looks better and more native

What are your first impressions on it?

6 Likes

The app is cool~!
And I have paid for the donation 3~
Finally, i can exercise OCaml on my cell phone.

But, I think the last vertion of the app is better for me.
For example, the current version of the app can not run this demo as the last version:

open Js_of_ocaml
open Js_of_ocaml_lwt
open Js_of_ocaml_tyxml


let display x =
  Dom.appendChild
    (Dom_html.getElementById "output")
    (Tyxml_js.To_dom.of_element x)

let _ =
  Tyxml_js.(
    Html.(
      div
        [ canvas
            ~a:[a_id "test-canvas";
                a_width 300;
                a_height 300] []
        ]))
  |> display


open Graphics_js

let by_id_coerce s f =
  Js.Opt.get
    (f (Dom_html.getElementById s))
    (fun () -> raise Not_found)

let _ =
  open_canvas
    (by_id_coerce "test-canvas"
                  Dom_html.CoerceTo.canvas)

let c = 3
let x0 = 0
and x1 = size_x ()
and y0 = 0
and y1 = size_y ()


let draw_ball x y =
  set_color foreground;
  fill_circle x y c

let state = ref (Lwt.task ())

let wait () = fst !state

let rec pong_aux x y dx dy =
  draw_ball x y;
  let new_x = x + dx and new_y = y + dy in
  let new_dx = if new_x - c <= x0 || new_x + c >= x1 then -dx else dx
  and new_dy = if new_y - c <= y0 || new_y + c >= y1 then -dy else dy in
  Lwt.bind (wait ()) (fun () -> pong_aux new_x new_y new_dx new_dy)

let rec start () =
  let t = Lwt.task () in
  let _, w = !state in
  state := t;
  clear_graph ();
  Lwt.wakeup w ();
  Lwt.bind (Lwt_js.sleep (1. /. 60.)) start

let pong x y dx dy = pong_aux x y dx dy

let _ = pong 111 87 2 3

let _ = pong 28 57 5 3

let _ = start ()
;;

And the button for reset console was disapeared …

1 Like

As I have redesigned everything using a new Framework for user interface (SwiftUI now, UIKit before), I forgot to add the reset button back in the new version.

Also, the new console is made with native elements, no more WebView shown, that’s why if you add elements to the dom they won’t be displayed.

And for the next update I also plan to detect if OCaml is already installed on the system (for example on macOS if you already installed OCaml via Homebrew) to run system version instead of embedded one, and in that case opam will be available etc…

I think the WebView is just fine.
I can play some JS things on it, some things more useful than just print.

If I need to write things seriously, I will take emacs or vscode …

you should make an utop GUI for the Mac out of it :slight_smile: would be a great tool.

regards

1 Like

What would you include in this GUI? Currently the app has a toplevel on the right side, so user can try some pieces of code directly in it. I need more details to see what you really mean

1 Like