[HN Gopher] Programming a space invader in OCaml and OpenGL: les... ___________________________________________________________________ Programming a space invader in OCaml and OpenGL: lessons learned Author : juliendemangeon Score : 90 points Date : 2020-02-21 14:02 UTC (8 hours ago) (HTM) web link (marmelab.com) (TXT) w3m dump (marmelab.com) | cpursley wrote: | Marmelab makes the pretty awesome react-admin library for | autogenerating admin interfaces: | | https://github.com/marmelab/react-admin | | I'd love to see an official Marmelab adapter so I can build my | admin interfaces with ReasonML. | Kmaschta wrote: | We already have hard time migrating it to TypeScript :p How | such an adapter might work? | adamnemecek wrote: | Between reasonml and elm which one should I pick? | weavie wrote: | If you've not used an ML before, start with Elm. | | Once you feel you have that sussed - it shouldn't take too long | - pull up ReasonML and give it a go. Use the Bucklscript-Tea | library - the architecture will be familiar from Elm. | | Then give Reason-React a go. | | Once that itch has been scratched move on to PureScript for a | whole new rabbit hole to fall down. | adamnemecek wrote: | I mean I'm familiar with ml and haskell, I'm more interested | in what's the best platform for building things. The language | itself is only a part of the equation. | azangru wrote: | I believe Reason is more practical (easier FFI), but as for | building things, at this point it's probably Typescript :-) | | Reason still hasn't had its async story ironed out, and has | poor support for Unicode[0] | | [0] "ReasonML strings are encoded as UTF-8 and not | compatible with JavaScript's UTF-16 strings" (from | https://2ality.com/2017/12/basic-types-reasonml.html) | azangru wrote: | Does Purescript also come into the equation? :-) | SkySkimmer wrote: | >Even though it is known for its robustness and its large | standard library | | I thought the ocaml stdlib was relatively small though? | rwmj wrote: | dnf install ocaml ocaml-lablgl-devel | | ? | | Anyway here's a toy game I wrote in GL + ODE + OCaml years ago: | https://github.com/fccm/OCamlODE/blob/master/examples/katama... | vzaliva wrote: | This article title and conclusions are misleading. It shows how | to write a simple game in OCaml and then proceeds to conclude | that ReasonML is better. I would expect the author to have the | same game implemented in ReasonML for comparison to show us why. | Otherwise, it is not very convincing. | gameswithgo wrote: | having done some OCaml and F#, where F#'s syntax is more like | reason, i think it is pretty clear that OCaml is a fascinating | language but what does impose some weird syntactic work that | both reason and f# relieve you of. probably to someone | sufficiently used to ocaml it doesn't matter but it can hurt | adoption | sdegutis wrote: | I always thought ReasonML was just a more JavaScript-ish | syntax on top of OCaml, not necessarily better but just | different. In what ways is it an actual _improvement_? | nv-vn wrote: | I don't see how you can say F#'s syntax is more like Reason. | OCaml and F# have nearly identical syntax for the core | language, with the few differences being: | | 1) places features diverged | | 2) modules | | 3) F#'s "light" syntax mode | | None of these really seem like Reason at all. Do you have any | specific places where they're similar? | dang wrote: | We've changed the title to that of the article, as the site | guidelines ask | (https://news.ycombinator.com/newsguidelines.html). | | Submitted title was "Is ReasonML good by itself or the | underlying OCaml the source of awesomeness?" | alharith wrote: | I am confused by this article. It went an entirely different | direction based on the question proposed. It was all | entertaining, nonetheless, but besides some passing comments to | Reason's documentation being better, the question does not seem | to be explored much by this article. It's a good article and | should be renamed to maybe "Getting started with OCaml and | OpenGL" | juliendemangeon wrote: | You're absolutely right. I wanted to justify my exploration by | way of comparison between ReasonML and Ocaml. | | The title ("Programming A Space Invader In OCaml and OpenGL: | Lessons Learned") still fits with the content, don't you think? | alharith wrote: | I see that now, yes I do. I think maybe the headings and | subheadings are also throwing me off as well. I wasn't sure | if I was reading one of those types of blogs that have a | continuous feed of articles on one page. | pjmlp wrote: | The underlying OCaml naturally. | | Having learned ML via Objective Caml's predecessor, Caml Light, | ReasonML seems to be just sugar coating for those with aversion | to ML classical syntax. | hellofunk wrote: | > ReasonML seems to be just sugar coating | | That's exactly what it is, no secret about that, that's the | goal of that project. | pjmlp wrote: | Which begs the question why not learn the real deal, instead | of adding another layer to debug. | | Programing isn't poetry. | mhd wrote: | > Programing isn't poetry. | | First time I've heard a C-like syntax described as | "poetic". | sshine wrote: | You could say the same thing about Erlang and Elixir. | | Or Java and Kotlin / Scala. | | Depending on how well an alternative syntax is requested | and adopted by the existing ecosystem surrounding the | particular VM, YMMV. Without knowing, I think you get quite | different answers in each case. | pjmlp wrote: | I not only could, I say so. | | Focus on platform languages and you always win long term. | k__ wrote: | True. | | But the accumulation of @-signs, for example, seems to be a | bit much. | msla wrote: | Programming is expressing programmer intent to the greatest | extent possible given technological constraints. Sometimes, | that's moving from machine code to assembly language[1]; | sometimes, that's building a declarative language to | express some specific logic. Finding new ways to preserve | programmer intent in machine-checkable ways (that is, not | just by adding comments) is one of the consistent goals of | programming language design. | | [1] Yes, humans used to write machine code. By hand. | Computers were for serious work, not mere clerical tasks | such as translating mnemonic order codes to binary and | doing address arithmetic. | pcwalton wrote: | Because people who know other programming languages, but | not ML, might want to read your code, and it's nice if it | looks familiar to them. | pjmlp wrote: | That is how languages like Go get designed, pour souls | not able to spend some time learning. | pcwalton wrote: | I _wish_ Go had been a reskin of OCaml. | dean177 wrote: | There is no layer above, it's not like coffeescript which | compiles to another language. It's literally an alternative | syntax. | pjmlp wrote: | Sure it does, unless there is a ReasonML native compiler | with its own ecosystem now. | throwaway894345 wrote: | If it works properly there isn't another layer to debug | (and anyway, one has to debug OCaml's syntax as it is, so | it's more like trading one debug layer for another). I've | never had to debug into assembly before, for example. And | while syntax is normally just superficial, OCaml goes out | of its way to be obscure and I don't have time for that. | Especially with all of its other warts (stdlib issues, | crappy package management, crappy build tooling, still no | multithreading, etc). I eventually just gave up. Which is | too bad because the type system (absent the OO stuff) could | be useful. | [deleted] | jherdman wrote: | Because sometimes the layer on top can express ideas more | succinctly. A classic example is CoffeeScript's fat arrow | syntax. It expressed a pattern in JavaScript we didn't, at | the time, have a shorthand for. Example: | https://coffeescript.org/#fat-arrow | pjmlp wrote: | And now it is dead, leaving behind a pile of code to | rewrite in next cool toy. | no_wizard wrote: | Does Not look dead to me. last activity is within the | last 30 days or so. | | https://github.com/jashkenas/coffeescript/ | | Its not as _popular_ to be certain, though. | pjmlp wrote: | I bet Fortran and Cobol are getting more jobs offers than | CoffeeScript. | blunte wrote: | Whereby you seem to be making the case for "dead" | languages. | throwaway894345 wrote: | In fairness, it's dead because it was shitty and made | most things harder, and the things it did improve JS | copied. If OCaml fixes its syntax, then we won't have any | need for Reason. | pjmlp wrote: | There isn't anything to fix. | throwaway894345 wrote: | If you were right OCaml wouldn't be the only language | with a popular syntax veneer. | erichocean wrote: | TypeScript says hi. | throwaway894345 wrote: | TypeScript extends the syntax to support type | annotations; it's not trying to fundamentally fix JS | syntax. | erichocean wrote: | Now "static typing" _isn 't_ a fundamental part of a | language? -\_(tsu)_/- | staticassertion wrote: | Typescript makes virtually no changes to JS syntax, | except what's necessary to support types. | erichocean wrote: | TypeScript classes, constructors and enums say hi. | | Talk about moving the goalposts... | throwaway894345 wrote: | No one is moving the goalposts. TypeScript's raison | d'etre is to add static typing to JS. Reason's is to fix | the syntax. | | (Yes, TS adds new grammatical constructs, but grammatical | constructs are about grammar, not syntax, contra Reason). | pdimitar wrote: | As a guy who tried to get into OCaml development several | times, the language is not the problem at all. It's the | several different "standard" libraries, lack of good | official agreed upon tutorials and guides, and the fact | that it has a GIL and is essentially single-threaded. | | If OCaml had Erlang's runtime (parallelism and | concurrency via actors with message inboxes) it would | likely be the most used language. | | Its lack of adoption isn't at all related to syntax IMO. | Programmers use all sorts of quirky syntaxes and the | world hasn't ended yet. | throwaway894345 wrote: | > As a guy who tried to get into OCaml development | several times, the language is not the problem at all. | It's the several different "standard" libraries, lack of | good official agreed upon tutorials and guides, and the | fact that it has a GIL and is essentially single- | threaded. | | I agree that those things are pain points (I said as much | upthread), but clearly the language is also part of the | problem or else there would be no interest in Reason. | | > As a guy who tried to get into OCaml development | several times, the language is not the problem at all. | It's the several different "standard" libraries, lack of | good official agreed upon tutorials and guides, and the | fact that it has a GIL and is essentially single- | threaded. | | A big reason Erlang is similarly unpopular is its syntax | as well (many of the most popular languages are | dynamically typed, so we know it's not the type system). | This theory is supported by the relative popularity of | Elixir, which shares Erlang's runtime and which has | enjoyed a fair amount of popularity in a relatively short | time despite introducing a number of syntax- and non- | syntax-related quirks. OCaml on BEAM would certainly | appeal to the intersection of FP and static-typing | enthusiasts, but it would not remotely be popular. | pdimitar wrote: | > _OCaml on BEAM would certainly appeal to the | intersection of FP and static-typing enthusiasts, but it | would not remotely be popular._ | | I realise what I said is not an undisputable truth and I | wouldn't argue about it. I probably should have just said | that I am observing an almost global strive for dev teams | to be able to catch bugs earlier and to have a bit more | guarantees by the mere virtue of the program successfully | compiling. But it might be my filter bubble. | | This is why I said an OCaml with the BEAM guarantees | would likely rise very high; because my observations lead | me to the belief that people want more compile-time | guarantees. And yeah, that might be a skewed observation. | throwaway894345 wrote: | > I realise what I said is not an undisputable truth and | I wouldn't argue about it. I probably should have just | said that I am observing an almost global strive for dev | teams to be able to catch bugs earlier and to have a bit | more guarantees by the mere virtue of the program | successfully compiling. But it might be my filter bubble. | | I think this is a pretty broad pattern, but: | | 1. It's not happening in isolation; there's also a move | toward greater development velocity | | 2. There's lots of low-hanging fruit to be had--lots of | people can get tremendous safety benefits by moving from | languages like JS and Python to Go or TypeScript or | typed-Python even if they don't have as elegant a type | system as OCaml (and those alternatives don't require the | same tradeoffs as OCaml or even an OCaml on BEAM). | | > This is why I said an OCaml with the BEAM guarantees | would likely rise very high; because my observations lead | me to the belief that people want more compile-time | guarantees. And yeah, that might be a skewed observation. | | Like I said, I don't think it's a skewed observation, | it's just that there are other ways of getting most of | those compile-time safety benefits with fewer tradeoffs. | But I would be a huge fanboy of an OCaml-like type system | on BEAM (especially if it can have Go- or Rust-like | attentiveness to practical software engineering | concerns). | WorldMaker wrote: | On the other hand, if Reason were such a massive | improvement to OCaml syntax, where are the people | clamoring for F# to adopt more of Reason's ideas? | | (Admittedly, F# already shares a couple Reason ideas like | C-style comments instead of OCaml's traditional ones. So | the waters are clearly muddy here to begin with, but a | lot of the big things like let-binding scopes and ;; | versus ; presumably would be big F# requests if Reason | was so strongly superior to the inherited OCaml legacy.) | throwaway894345 wrote: | > where are the people clamoring for F# to adopt more of | Reason's ideas? | | Probably writing C#. | zem wrote: | reason isn't another layer, it's an alternate syntax. it | doesn't compile via translation to ocaml code; both reason | syntax and ocaml syntax compile to the same thing. | toolz wrote: | I disagree, code is for and by humans. There are likely | very real runtime consequences to having code that is | "ugly", because the next human to touch it will value it | less and do a suboptimal job. | | Of course all of this is highly subjective, but my | understanding is that it's important to consider if you | want highly successful projects. | wbl wrote: | ML syntax is fine. | Gene_Parmesan wrote: | > code is for and by humans | | I think this is very much domain dependent. Generally the | more important efficiency is, the less I find this to be | true. And really, code is always for the machine at the | end of the day. | | Additionally, if an added code layer makes the code more | difficult to debug, that's also making the code worse for | humans. Note I'm not arguing for or against whether | that's happening in the case of OCaml/ReasonML, just | making the point. | sshine wrote: | > code is always for the machine at the end of the day | | On the other hand, code is read much more than it is | written. | | You may also regard efficiency as a necessary evil if the | cost is readability. | | Ultimately the winning strategy in this regard is | achieving "free abstraction", making code that is both | readable and efficient. Different languages aim at this. | C++ has been best at this for most of history. Haskell | and Rust are competing at this now as well. | | OCaml isn't exactly efficient because of free | abstraction, but because of its extremely simple | translation strategies. OCaml's "flambda" compiler | extension wasn't released as stable until 4.03 (2016), | which means that before that, very little high-level | transformation was happening. | | My experience is that OCaml programmers care about low- | level optimization, for good and for bad. | | For example, in this StackOverflow response there are two | examples of a function 'partialsums': | | https://stackoverflow.com/questions/37694313/make-ocaml- | func... | | The one that Jeffrey Scofield provides is essentially | more efficient because the accumulated value is a list, | just like the end result, whereas my solution accumulates | a tuple, which means every iteration of the fold involves | boxing and unboxing that tuple. An optimizing compiler | working at a higher level of abstraction might figure | that out and re-use the memory of the tuple, but no sir. | hajile wrote: | The "real deal" here is Ocaml. It's not the most complex | syntax in existence, but I'd say it's _easily_ the most | complex ML language in existence. | jimbokun wrote: | > ReasonML seems to be just sugar coating for those with | aversion to ML classical syntax. | | So it's the Elixir to Ocaml's Erlang? | firethief wrote: | Elixir is a different language for the Erlang VM, but Reason | is just a different syntax for the OCaml language. There's a | 1:1 correspondence between their ASTs, and even a tool to | convert between them. | hajile wrote: | ReasonML is adversely affected by it's Ocaml base if anything. | StandardML would have been a much better base (they went with | Ocaml because it was a lower-effort to implement and Facebook has | a lot of Ocaml devs). | | The first bad part is that Ocaml _does not_ have a language spec. | The implementation is the spec. This puts them at the whim of the | Ocaml devs with no other options. SML is a standard with several | good implementations. | | Ocaml requires different operators for float and integer | arithmetic. SML assumes an integer type unless you include a | decimal. Both need to be replaced with module typeclasses (and | both are working in that direction). For SML though, your | existing code can continue to just work as it did before while | Ocaml will be left with lots of `+.` or `*.` operators | everywhere. | | Another mistake that bleeds through is mutable strings. This is | an outgrowth of all arrays being mutable. Immutable strings allow | efficient representation as ropes instead of normal arrays (along | with other optimizations that are good for GC'd languages). SML | has immutable strings and vectors along with arrays (which you | can still use as mutable strings of characters if you need them). | | For their React-like goal though, Ocaml's lack of anonymous | record types is the absolute worst. In SML, I can just type up a | record and pass it in (no type definitions required). When | passing in stuff to a component, you have to have all these named | arguments. In SML, I'd just pass an anonymous record and | destructure it in the function -- Just like in Javascript, but | with types behind the scenes to keep everything straight. | | Writing a custom parser for Babel like typescript or coffeescript | have done would have been better for the language design and | independence. | lindig wrote: | > Another mistake that bleeds through is mutable strings. | | OCaml strings are immutable by default since OCaml 4.06. | vphantom wrote: | FYI strings are now immutable in OCaml. It was a compiler | option starting with 4.02 and it has become enabled by default | since 4.06. | hajile wrote: | That's nice to know. On the flip side, that's not nice for | interaction between older code that wants to mutate and newer | code that wants to "copy". If the "copy" code is actually | copying all the time behind the scenes (something it has to | do if you are compiling with mutable strings for backward | compatibility with the rest of your codebase), that's a huge | performance hit. | nv-vn wrote: | Well there is a language spec [1], it's just designed by the | same people who develop the compiler. While there's only 1 de | facto implementation (same as Rust, Go, etc.) there's multiple | backends and lots of research work happens in different forks | of the language. There's usually quite a bit of discussion and | work that occurs between proposing a feature and integrating it | into the language. There's also various competing forces here | such as INRIA, Jane Street, OCamllabs, Reason developers, & | other typical OCaml developers each with their own agenda. It's | not so simple as the devs just adding something without any | input. | | >For their React-like goal though, Ocaml's lack of anonymous | record types is the absolute worst. | | The object system actually allows this to be fair & it does get | a little bit of use in some Reason libraries targeting React | developers | | I get that SML has advantages over OCaml but I don't really get | what you're trying to argue for. Clearly if you like SML you'd | prefer OCaml to JavaScript... | | [1] https://caml.inria.fr/pub/docs/manual-ocaml/language.html | sweeneyrod wrote: | ReasonML is just an alternative syntax for OCaml. Often people | use "ReasonML" shorthand for "ReasonML, converted to OCaml, | compiled to Javascript with BuckleScript" and "OCaml" for "OCaml | compiled natively" but it's perfectly possible (and actually | really easy) to use OCaml with BuckleScript and Reason natively. | | Also note that despite the "O" in the name, OOP in OCaml is rare | (for instance, there isn't any in the code in the article). | elcapitan wrote: | What's the state of using Reason natively? Last time I checked | all the documentation and examples where towards the | reason/js/react ecosystem. Are there any good native code | projects written in Reason to look at for reference? | k__ wrote: | Reprocessing is a rewrite of Processing in Reason. | | Runs with WebGL and OpenGL. | | https://github.com/Schmavery/reprocessing | sweeneyrod wrote: | People don't do it much, but if you're using the most popular | build system (dune) you can replace your .ml files with .re | ones and it will Just Work. So you can use OCaml projects for | reference (I think anyone who's doing Reason should have a | vague grasp of OCaml syntax, it's not really that different). | firethief wrote: | > I think anyone who's doing Reason should have a vague | grasp of OCaml syntax, it's not really that different | | Especially if you're targeting native, so all your | dependencies are written and documented in OCaml syntax. | pcvonz wrote: | Check out Oni Vim 2: | https://github.com/onivim/oni2/blob/master/README.md | elcapitan wrote: | That looks perfect, thanks! | nv-vn wrote: | Yep. This is an especially weird thing for some people to grasp | when working with native libraries developed in Reason (like | Revery, which most people assume is built on web tech). | juliendemangeon wrote: | You're right! The toolbox is far better too | kingkonz1 wrote: | > it is very complicated to install the base stack to develop in | OCaml | | I'm not sure why the author decided to use such a complicated | setup using Make and Docker. | | They could have just ran `opam switch create 4.09.0`, which would | have created the compiler, then `opam install ...` for the | dependencies. | | Still, an interesting article. I wouldn't recommending using | OCaml/ReasonML for gamedev since getting it to work with Windows | is pretty much impossible. | pnathan wrote: | It is complicated to figure out a straightforward way to do | builds in OCaml. If you're not tapped into the Current Way, you | kind of have to read this blog, read that fragment, piece it | together. I worked it through for a project of mine, and it was | unusually unpleasant vs, say, Haskell. | | Docker because, presumably, he didn't want to dink with | installing it locally. | srpablo wrote: | While I didn't try to use Docker (though we did use the same | pxhere image :-p), I also struggled to get a productive setup | of OCaml. Getting a switch running wasn't the hard part, it was | making the environment suitable for real project work. I had a | set of Make targets in mind (test, build, shell), some language | dev features I wanted (jump to definition, type of expression | under cursor), and some properties of the project (pinned | dependencies) such that it took a fair bit of fiddling with | dune/opam to get it working | https://morepablo.com/2019/08/fresco-jesus-ocaml-setup.html | | I find OCaml really enjoyable once I got going, but I do think | the initial setup is a major barrier to larger adoption. I | think a post on howistart.org might be useful, but it'd | probably be polarizing since most functions have two major ways | of doing it (Jane Street vs. not, Lwt vs. Async, etc.). | yodsanklai wrote: | I agree it's quite annoying to set up an OCaml project, and | all the Jane Street stuff makes it even more confusing for | newcomers. But to be fair, it may be the case with other | languages as well. I recently tried to learn some Javascript, | and I spent some time understanding the tooling and package | management (npm/yarn, bundling, transpiling, node vs browser, | difference between javascript versions). | nickserv wrote: | Modern JavaScript is a major pain to set up, but the | difference with other languages is that for some things | it's the only language available. | bryanrasmussen wrote: | This seems sort of like comparing the complexities of | learning German to a level of fluency with the complexities | of learning English, differences between major variant | forms of English, with a deep dive into the history of the | English Language and its poetics. | nv-vn wrote: | Agreed, the choice to use obuild was also bizarre. Dune has | been standard for the last ~2 years and before that Oasis was | the most popular build tool I believe. ___________________________________________________________________ (page generated 2020-02-21 23:00 UTC)